diff options
Diffstat (limited to 'src')
61 files changed, 7729 insertions, 1786 deletions
@@ -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,7 @@ #include "H5Opkg.h" /* Object headers */ #include "H5Sprivate.h" /* Dataspace functions */ #include "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -66,10 +67,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 */ @@ -220,31 +217,38 @@ 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 */ + H5P_genplist_t *plist; /* Property list pointer */ + void *location = NULL; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, acpl_id, aapl_id); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == H5I_get_type(loc_id) || H5I_DATATYPE == 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") + + /* set creation properties */ + if(H5P_set(plist, H5A_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5A_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5A_CRT_LOCATION_NAME, &location) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for location") + + /* Create the attribute through the VOL */ + if((ret_value = H5VL_attr_create(loc_id, attr_name, acpl_id, aapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute") done: FUNC_LEAVE_API(ret_value) @@ -287,13 +291,9 @@ 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 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 */ + H5P_genplist_t *plist; /* Property list pointer */ + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -301,40 +301,48 @@ H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, acpl_id, aapl_id, lapl_id); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == H5I_get_type(loc_id) || H5I_DATATYPE == 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); - /* Find the object's location */ - if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) + /* Find the object's location + if(H5G_loc_find(&loc, obj_name, &obj_loc, lapl_id, H5AC_ind_dxpl_id) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; + */ - /* 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") + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup(loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, obj_name, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") -done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + /* 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") + + /* set creation properties */ + if(H5P_set(plist, H5A_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5A_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5A_CRT_LOCATION_NAME, &location) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for location") + + /* Create the attribute through the VOL */ + if((ret_value = H5VL_attr_create(loc_id, attr_name, acpl_id, aapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute") +done: + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* H5Acreate_by_name() */ @@ -528,41 +536,24 @@ 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 */ hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("i", "i*si", loc_id, attr_name, aapl_id); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) - - /* Finish initializing attribute */ - if(H5A_open_common(&loc, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize 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") + /* Open the attribute through the VOL */ + if((ret_value = H5VL_attr_open(loc_id, NULL, attr_name, aapl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open attribute") 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() */ @@ -592,18 +583,16 @@ 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) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute opened */ + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE5("i", "i*s*sii", loc_id, obj_name, attr_name, aapl_id, lapl_id); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) @@ -614,20 +603,19 @@ 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") + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup(loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, obj_name, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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") + /* Open the attribute through the VOL */ + if((ret_value = H5VL_attr_open(loc_id, location, attr_name, aapl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open attribute") 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 (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* H5Aopen_by_name() */ @@ -660,8 +648,6 @@ 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) { - H5A_t *attr = NULL; /* Attribute opened */ - H5G_loc_t loc; /* Object location */ hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -669,10 +655,8 @@ H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, lapl_id); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) @@ -685,20 +669,11 @@ 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") + if(H5VL_attr_generic(loc_id, H5VL_ATTR_OPEN_BY_IDX, &ret_value, + obj_name, idx_type, order, n, aapl_id, lapl_id) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to open attribute") 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() */ @@ -721,7 +696,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) { herr_t ret_value = SUCCEED; /* Return value */ @@ -908,24 +883,18 @@ 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 */ 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") + /* write the data through the VOL */ + if((ret_value = H5VL_attr_write(attr_id, dtype_id, buf)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data") done: FUNC_LEAVE_API(ret_value) @@ -948,7 +917,7 @@ done: DESCRIPTION This function writes a complete attribute to disk. --------------------------------------------------------------------------*/ -static herr_t +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 */ @@ -1065,24 +1034,18 @@ 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 */ 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") + /* Read the data through the VOL */ + if((ret_value = H5VL_attr_read(attr_id, dtype_id, buf)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data") done: FUNC_LEAVE_API(ret_value) @@ -1105,7 +1068,7 @@ done: DESCRIPTION This function reads a complete attribute from disk. --------------------------------------------------------------------------*/ -static herr_t +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*/ @@ -1211,31 +1174,58 @@ 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 */ 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") + /* get the dataspace through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_SPACE, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get data space") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aget_space() */ + + +/*------------------------------------------------------------------------- + * 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") + 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) - (void)H5S_close(ds); + 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_API(ret_value) -} /* H5Aget_space() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_space() */ /*-------------------------------------------------------------------------- @@ -1257,16 +1247,41 @@ 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 */ 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") + /* get the datatype through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_TYPE, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get type") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aget_type() */ + + +/*------------------------------------------------------------------------- + * 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) @@ -1278,7 +1293,7 @@ H5Aget_type(hid_t attr_id) * read-only. */ if(NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype") + 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) @@ -1286,7 +1301,7 @@ H5Aget_type(hid_t attr_id) /* Lock copied type */ if(H5T_lock(dt, FALSE) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype") /* Atomize */ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) @@ -1295,11 +1310,11 @@ H5Aget_type(hid_t attr_id) done: if(ret_value < 0) { if(dt && H5T_close(dt) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release datatype") + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") } /* end if */ - FUNC_LEAVE_API(ret_value) -} /* H5Aget_type() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_type() */ /*-------------------------------------------------------------------------- @@ -1324,10 +1339,6 @@ 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; FUNC_ENTER_API(FAIL) @@ -1335,9 +1346,40 @@ H5Aget_create_plist(hid_t 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") + /* get the acpl through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_ACPL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get acpl") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Aget_create_plist() */ + + +/*-------------------------------------------------------------------------- + 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") @@ -1354,7 +1396,7 @@ H5Aget_create_plist(hid_t attr_id) ret_value = new_plist_id; done: - FUNC_LEAVE_API(ret_value) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5Aget_create_plist() */ @@ -1382,21 +1424,18 @@ 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; 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") + /* get the name through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_NAME, &ret_value, buf_size, buf) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get name") done: FUNC_LEAVE_API(ret_value) @@ -1472,8 +1511,7 @@ 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 */ + hid_t attr_id = -1; ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1481,10 +1519,8 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, lapl_id); /* Check args */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) @@ -1497,6 +1533,15 @@ 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") + if(H5VL_attr_generic(loc_id, H5VL_ATTR_OPEN_BY_IDX, &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, &ret_value, size, name) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get name") + +#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") @@ -1510,10 +1555,11 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if((size_t)ret_value >= size) name[size - 1]='\0'; } /* end if */ +#endif done: /* Release resources */ - if(attr && H5A_close(attr) < 0) + if(attr_id > 0 && H5VL_attr_close(attr_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") FUNC_LEAVE_API(ret_value) @@ -1540,18 +1586,14 @@ done: hsize_t H5Aget_storage_size(hid_t attr_id) { - H5A_t *attr; /* Attribute object for ID */ 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") - - /* Set return value */ - ret_value = attr->shared->data_size; + /* get the storage size through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_STORAGE_SIZE, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, 0, "unable to get acpl") done: FUNC_LEAVE_API(ret_value) @@ -1574,19 +1616,14 @@ done: herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo) { - H5A_t *attr; /* Attribute object for name */ 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 attribute information */ - if(H5A_get_info(attr, ainfo) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") + /* get the attribute info through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_INFO, ainfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") done: FUNC_LEAVE_API(ret_value) @@ -1610,18 +1647,17 @@ 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 */ + hid_t attr_id = -1; + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*s*xi", loc_id, obj_name, attr_name, ainfo, lapl_id); /* Check args */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) @@ -1633,7 +1669,7 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, else if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - +#if 0 /* 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") @@ -1641,12 +1677,28 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, /* Get the attribute information */ if(H5A_get_info(attr, ainfo) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") +#endif + + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup(loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, obj_name, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") + /* Open the attribute through the VOL */ + if((attr_id = H5VL_attr_open(loc_id, location, attr_name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open attribute") + + /* get the attribute info through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_INFO, ainfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") done: - /* Cleanup on failure */ - if(attr && H5A_close(attr) < 0) + /* release resources */ + if(attr_id > 0 && H5VL_attr_close(attr_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Aget_info_by_name() */ @@ -1669,8 +1721,7 @@ 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 */ + hid_t attr_id = FAIL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1678,10 +1729,8 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, lapl_id); /* Check args */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) @@ -1696,6 +1745,7 @@ 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") +#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") @@ -1703,10 +1753,20 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, /* Get the attribute information */ if(H5A_get_info(attr, ainfo) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") +#endif + + /* open the attribute through the VOL */ + if(H5VL_attr_generic(loc_id, H5VL_ATTR_OPEN_BY_IDX, &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, ainfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") done: /* Release resources */ - if(attr && H5A_close(attr) < 0) + if(attr_id && H5VL_attr_close(attr_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") FUNC_LEAVE_API(ret_value) @@ -1993,11 +2053,8 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data, 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 */ + void *location = NULL; + hid_t obj_loc_id = (-1); /* ID for object located */ H5A_attr_iter_op_t attr_op; /* Attribute operator */ hsize_t start_idx; /* Index of attribute to start iterating at */ @@ -2009,10 +2066,8 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, op_data, lapl_id); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) @@ -2025,19 +2080,13 @@ H5Aiterate_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") - /* 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 token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, obj_name, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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; - - /* Open the object */ - 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") + /* Open the object through the VOL */ + if((obj_loc_id = H5VL_object_open_by_loc(loc_id, location, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") /* Build attribute operator info */ attr_op.op_type = H5A_ATTR_OP_APP2; @@ -2058,8 +2107,6 @@ done: if(H5I_dec_app_ref(obj_loc_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") } /* end if */ - else 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) } /* H5Aiterate_by_name() */ @@ -2274,13 +2321,9 @@ H5Aclose(hid_t attr_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", attr_id); - /* check arguments */ - if(NULL == H5I_object_verify(attr_id, H5I_ATTR)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - - /* Decrement references to that atom (and close it) */ - if(H5I_dec_app_ref(attr_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute") + /* Close the attribute through the VOL */ + if((ret_value = H5VL_attr_close(attr_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to close attribute") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c index 22faaa2..96c03e8 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,31 +139,38 @@ 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 *location = NULL; + H5P_genplist_t *plist; /* Property list pointer */ hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("i", "i*siii", loc_id, name, type_id, space_id, plist_id); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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, H5A_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5A_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5A_CRT_LOCATION_NAME, &location) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for location") + + /* Create the attribute through the VOL */ + if((ret_value = H5VL_attr_create(loc_id, name, plist_id, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute") done: FUNC_LEAVE_API(ret_value) @@ -194,35 +202,22 @@ done: hid_t H5Aopen_name(hid_t loc_id, const char *name) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute opened */ hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE2("i", "i*s", loc_id, name); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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) - - /* 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") + /* Open the attribute through the VOL */ + if((ret_value = H5VL_attr_open(loc_id, NULL, name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open attribute") 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_name() */ @@ -252,33 +247,20 @@ done: hid_t H5Aopen_idx(hid_t loc_id, unsigned idx) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute opened */ hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE2("i", "iIu", loc_id, idx); /* check arguments */ - if(H5I_ATTR == H5I_get_type(loc_id)) + if(H5I_ATTR_PUBLIC == 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") + if(H5VL_attr_generic(loc_id, H5VL_ATTR_OPEN_BY_IDX, &ret_value, ".", H5_INDEX_CRT_ORDER, + H5_ITER_INC, (hsize_t)idx, H5P_DEFAULT, H5P_LINK_ACCESS_DEFAULT) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataset access properties") 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_idx() */ @@ -302,14 +284,33 @@ done: Deprecated in favor of H5Oget_info --------------------------------------------------------------------------*/ int -H5Aget_num_attrs(hid_t loc_id) +H5Aget_num_attrs(hid_t id) { H5O_loc_t *loc; /* Object location for attribute */ void *obj; + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + hid_t loc_id; + H5I_type_t id_type; int ret_value; FUNC_ENTER_API(FAIL) - H5TRACE1("Is", "i", loc_id); + H5TRACE1("Is", "i", id); + + id_type = H5I_get_type(id); + /* get the actual ID from an upper ID level */ + /* MSC - this is a workaround to allow the test suite to pass and + at some point needs to be removed once all high level operations + that needs to go through the VOL actually go through the VOL*/ + if (H5I_FILE_PUBLIC == id_type || H5I_GROUP_PUBLIC == id_type || + H5I_DATASET_PUBLIC == id_type || H5I_DATATYPE_PUBLIC == id_type || + H5I_ATTR_PUBLIC == id_type) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, NULL, "invalid user identifier") + loc_id = id_wrapper->obj_id; + } + else { + loc_id = id; + } /* check arguments */ if(H5I_BADID == H5I_get_type(loc_id)) diff --git a/src/H5Apkg.h b/src/H5Apkg.h index 26c8dff..5257171 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -194,10 +194,16 @@ H5_DLL H5A_t *H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, 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..ac9f698 100644 --- a/src/H5Aprivate.h +++ b/src/H5Aprivate.h @@ -31,7 +31,10 @@ /**************************/ /* Library Private Macros */ /**************************/ - +/* ======== Attribute creation property names ======== */ +#define H5A_CRT_TYPE_ID_NAME "attr_type_id" +#define H5A_CRT_SPACE_ID_NAME "attr_space_id" +#define H5A_CRT_LOCATION_NAME "attr_location" /****************************/ /* Library Private Typedefs */ @@ -31,7 +31,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ - +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -63,10 +63,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 */ /*******************/ @@ -127,22 +123,15 @@ 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 */ + H5P_genplist_t *plist; /* Property list pointer */ hid_t ret_value; /* 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,16 +154,23 @@ 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, H5D_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5D_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5D_CRT_LCPL_ID_NAME, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id") + + /* Create the dataset through the VOL */ + if((ret_value = H5VL_dataset_create(loc_id, name, dcpl_id, dapl_id)) < 0) 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") done: - if(ret_value < 0) - if(dset && H5D_close(dset) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Dcreate2() */ @@ -219,21 +215,13 @@ 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 */ + 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,32 +235,20 @@ 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))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") + /* 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") - /* 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") + /* set creation properties */ + if(H5P_set(plist, H5D_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5D_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + /* Create the dataset through the VOL */ + if((ret_value = H5VL_dataset_create(loc_id, NULL, dcpl_id, dapl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") 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) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Dcreate_anon() */ @@ -298,22 +274,12 @@ 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 */ 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,41 +290,10 @@ 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); - - /* 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; - - /* 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") - - /* 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") - - /* 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") - + /* Open the dataset through the VOL */ + if((ret_value = H5VL_dataset_open(loc_id, name, dapl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open dataset") 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 */ FUNC_LEAVE_API(ret_value) } /* end H5Dopen2() */ @@ -386,20 +321,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") - - /* - * Decrement the counter on the dataset. It will be freed if the count - * reaches zero. - * - * Pass in TRUE for the 3rd parameter to tell the function to remove - * dataset's ID even though the freeing function might fail. Please - * see the comments in H5I_dec_ref for details. (SLU - 2010/9/7) - */ - if(H5I_dec_app_ref_always_close(dset_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + /* Close the dataset through the VOL */ + if((ret_value = H5VL_dataset_close(dset_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to close dataset") done: FUNC_LEAVE_API(ret_value) @@ -425,33 +349,15 @@ done: hid_t H5Dget_space(hid_t dset_id) { - H5D_t *dset = NULL; - H5S_t *space = NULL; - hid_t ret_value; + 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 dataspace through the VOL */ + if(H5VL_dataset_get(dset_id, H5VL_DATASET_GET_SPACE, &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 +379,14 @@ done: herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation) { - H5D_t *dset = NULL; 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") - - /* Read data space address and return */ - if(FAIL==(ret_value=H5D_get_space_status(dset, allocation, H5AC_ind_dxpl_id))) - 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_id, H5VL_DATASET_GET_SPACE_STATUS, allocation)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get space status") done: FUNC_LEAVE_API(ret_value) @@ -511,44 +412,16 @@ 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 */ + 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") - - /* 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_id, H5VL_DATASET_GET_TYPE, &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 +445,15 @@ 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 */ + 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; + if(H5VL_dataset_get(dset_id, H5VL_DATASET_GET_DCPL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataset creation properties") 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") - FUNC_LEAVE_API(ret_value) } /* end H5Dget_create_plist() */ @@ -710,45 +494,14 @@ 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 */ + 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; - + if(H5VL_dataset_get(dset_id, H5VL_DATASET_GET_DAPL, &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,18 +528,14 @@ done: hsize_t H5Dget_storage_size(hid_t dset_id) { - H5D_t *dset; /* Dataset to query */ 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") - - /* Set return value */ - ret_value = H5D_get_storage_size(dset, H5AC_ind_dxpl_id); + /* get storage size through the VOL */ + if(H5VL_dataset_get(dset_id, H5VL_DATASET_GET_STORAGE_SIZE, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, 0, "unable to get storage size") done: FUNC_LEAVE_API(ret_value) @@ -810,18 +559,14 @@ done: haddr_t H5Dget_offset(hid_t dset_id) { - H5D_t *dset; /* Dataset to query */ 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") - - /* Set return value */ - ret_value = H5D_get_offset(dset); + /* get offset through the VOL */ + if(H5VL_dataset_get(dset_id, H5VL_DATASET_GET_OFFSET, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, HADDR_UNDEF, "unable to get offset") done: FUNC_LEAVE_API(ret_value) @@ -902,7 +647,7 @@ H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator") if(NULL == buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer") - if(H5I_DATATYPE != H5I_get_type(type_id)) + if(H5I_DATATYPE != H5I_get_type(type_id) && H5I_DATATYPE_PUBLIC != H5I_get_type(type_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype") if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") @@ -941,7 +686,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) && H5I_DATATYPE_PUBLIC != 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") @@ -1002,8 +748,9 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, H5TRACE4("e", "iii*h", dataset_id, type_id, space_id, size); /* Check args */ - if(H5I_DATASET != H5I_get_type(dataset_id) || - H5I_DATATYPE != H5I_get_type(type_id) || size == NULL) + if(H5I_DATASET_PUBLIC != H5I_get_type(dataset_id) || + (H5I_DATATYPE != H5I_get_type(type_id) && H5I_DATATYPE_PUBLIC != 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") @@ -1085,21 +832,17 @@ done: herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]) { - H5D_t *dset; /* Dataset for this operation */ 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") + /* set the extent through the VOL */ + if((ret_value = H5VL_dataset_set_extent(dset_id, size)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 7e65149..a2de87f 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,41 +141,36 @@ 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 */ + 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))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") + /* 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") - /* 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") + /* set creation properties */ + if(H5P_set(plist, H5D_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5D_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5D_CRT_LCPL_ID_NAME, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id") + + /* Create the dataset through the VOL */ + if((ret_value = H5VL_dataset_create(loc_id, name, dcpl_id, H5P_DATASET_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") done: - if(ret_value < 0) - if(dset && H5D_close(dset) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Dcreate1() */ @@ -201,61 +196,21 @@ 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 */ 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); - - /* 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; - - /* 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") - - /* 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") - - /* 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") + /* Open the dataset through the VOL */ + if((ret_value = H5VL_dataset_open(loc_id, name, dapl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open dataset") 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 */ FUNC_LEAVE_API(ret_value) } /* end H5Dopen1() */ diff --git a/src/H5Dint.c b/src/H5Dint.c index 28d5367..e17c0f7 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -103,6 +103,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; @@ -1917,7 +1920,7 @@ H5D_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t op, /* Check args */ HDassert(buf); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(H5I_DATATYPE == H5I_get_type(type_id) || H5I_DATATYPE_PUBLIC == H5I_get_type(type_id)); HDassert(space); HDassert(H5S_has_extent(space)); HDassert(op); @@ -1953,7 +1956,7 @@ H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, void *buf) FUNC_ENTER_NOAPI(FAIL) /* Check args */ - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(H5I_DATATYPE == H5I_get_type(type_id) || H5I_DATATYPE_PUBLIC == H5I_get_type(type_id)); HDassert(space); HDassert(H5P_isa_class(plist_id, H5P_DATASET_XFER)); HDassert(buf); @@ -2040,7 +2043,7 @@ H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, unsigned UNUSED ndim, co FUNC_ENTER_NOAPI_NOINIT HDassert(op_data); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(H5I_DATATYPE == H5I_get_type(type_id) || H5I_DATATYPE_PUBLIC == H5I_get_type(type_id)); /* Check args */ if(NULL == (dt = (H5T_t *)H5I_object(type_id))) @@ -2443,3 +2446,270 @@ 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((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 06e4417..7a58c4a 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -28,6 +28,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ +#include "H5VLprivate.h" /* VOL plugins */ #ifdef H5_HAVE_PARALLEL /* Remove this if H5R_DATASET_REGION is no longer used in this file */ @@ -49,14 +50,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); - /* 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, @@ -121,58 +114,25 @@ 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 */ 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(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; - /* 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_id, mem_type_id, mem_space_id, + file_space_id, plist_id, buf)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") + done: FUNC_LEAVE_API(ret_value) } /* end H5Dread() */ @@ -213,10 +173,6 @@ 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) { - 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 */ FUNC_ENTER_API(FAIL) @@ -224,26 +180,6 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, dxpl_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(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 */ /* Get the default dataset transfer property list if the user didn't provide one */ if(H5P_DEFAULT == dxpl_id) @@ -251,18 +187,10 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, else if(TRUE != H5P_isa_class(dxpl_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; - /* write raw data */ - if(H5D_write(dset, mem_type_id, mem_space, file_space, dxpl_id, buf) < 0) + /* Write the data through the VOL */ + if((ret_value = H5VL_dataset_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 write data") done: @@ -283,7 +211,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*/) { @@ -485,7 +413,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/H5Dprivate.h b/src/H5Dprivate.h index 48966db..c7a8cdc 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -47,6 +47,9 @@ #define H5D_CRT_FILL_VALUE_NAME "fill_value" /* Fill value */ #define H5D_CRT_ALLOC_TIME_STATE_NAME "alloc_time_state" /* Space allocation time state */ #define H5D_CRT_EXT_FILE_LIST_NAME "efl" /* External file list */ +#define H5D_CRT_TYPE_ID_NAME "dataset_type_id" /* datatype id */ +#define H5D_CRT_SPACE_ID_NAME "dataset_space_id" /* dataspace id */ +#define H5D_CRT_LCPL_ID_NAME "dataset_lcpl_id" /* lcpl id */ /* ======== Dataset access property names ======== */ #define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */ @@ -156,6 +159,13 @@ typedef struct H5D_copy_file_ud_t { /******************************/ /* Library Private Prototypes */ /******************************/ +/* Internal I/O routines */ +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); @@ -164,6 +174,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, diff --git a/src/H5Edefin.h b/src/H5Edefin.h index ee284c4..27275a3 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -26,6 +26,7 @@ hid_t H5E_FILE_g = FAIL; /* File accessability */ 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 6881e48..99467ee 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 967b248..68c605c 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 accessability */ 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 5edcd34..28d822a 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= @@ -34,6 +34,7 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5SMprivate.h" /* Shared Object Header Messages */ #include "H5Tprivate.h" /* Datatypes */ +#include "H5VLprivate.h" /* VOL plugins */ /* Struct only used by functions H5F_get_objects and H5F_get_objects_cb */ typedef struct H5F_olist_t { @@ -59,7 +60,6 @@ static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, 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); /* Declare a free list to manage the H5F_t struct */ H5FL_DEFINE(H5F_t); @@ -183,24 +183,15 @@ H5F_term_interface(void) *------------------------------------------------------------------------- */ hid_t -H5Fget_create_plist(hid_t file_id) +H5Fget_create_plist(hid_t uid) { - H5F_t *file; /* File info */ - H5P_genplist_t *plist; /* Property list */ 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") + H5TRACE1("i", "i", uid); - /* 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(uid, H5VL_FILE_GET_FCPL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file creation properties") done: FUNC_LEAVE_API(ret_value) @@ -229,21 +220,15 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Fget_access_plist(hid_t file_id) +H5Fget_access_plist(hid_t uid) { - H5F_t *f; /* File info */ 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") + H5TRACE1("i", "i", uid); - /* 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(uid, H5VL_FILE_GET_FAPL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file creation properties") done: FUNC_LEAVE_API(ret_value) @@ -336,6 +321,11 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) 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") + /* Increment the reference count on the VOL struct and insert it into the property list */ + f->vol_cls->nrefs ++; + if(H5P_set(new_plist, H5F_ACS_VOL_NAME, &(f->vol_cls)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file VOL plugin") + /* 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) @@ -369,14 +359,21 @@ done: ssize_t H5Fget_obj_count(hid_t file_id, unsigned types) { - H5F_t *f = NULL; /* File to query */ + H5F_t *f = NULL; /* File to query */ + ssize_t ret_value; /* Return value */ size_t obj_count = 0; /* Number of opened objects */ - ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("Zs", "iIu", file_id, types); - /* Check arguments */ + if (H5I_FILE_PUBLIC == H5I_get_type(file_id)) { + H5VL_id_wrapper_t *id_wrapper; /* wrapper object */ + + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + file_id = id_wrapper->obj_id; + } + 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)) @@ -447,13 +444,21 @@ 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 */ + H5F_t *f = NULL; /* File to query */ size_t obj_id_count = 0; /* Number of open objects */ ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("Zs", "iIuz*i", file_id, types, max_objs, oid_list); + if (H5I_FILE_PUBLIC == H5I_get_type(file_id)) { + H5VL_id_wrapper_t *id_wrapper; /* wrapper object */ + + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + file_id = id_wrapper->obj_id; + } + /* 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") @@ -468,6 +473,9 @@ H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list) /* Set the return value */ ret_value = (ssize_t)obj_id_count; + if (H5VL_replace_with_uids (oid_list, ret_value) <= 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get IDs") + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_obj_ids() */ @@ -623,9 +631,9 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) /* 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) ))) { + (!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; @@ -673,6 +681,7 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) case H5I_DATASPACE: case H5I_REFERENCE: case H5I_VFL: + case H5I_VOL: case H5I_GENPROP_CLS: case H5I_GENPROP_LST: case H5I_ERROR_CLASS: @@ -730,25 +739,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle) +H5Fget_vfd_handle(hid_t uid, hid_t fapl, void **file_handle) { - H5F_t *file; /* File to query */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE3("e", "ii**x", file_id, fapl, file_handle); + H5TRACE3("e", "ii**x", uid, fapl, file_handle); /* Check args */ 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") - - /* 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_get(uid, H5VL_FILE_GET_VFD_HANDLE, file_handle, fapl)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file handle") done: FUNC_LEAVE_API(ret_value) @@ -1326,6 +1329,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") + /* Store a pointer to the VOL plugin in the file struct */ + if(H5P_get(a_plist, H5F_ACS_VOL_NAME, &(file->vol_cls)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin") + /* * 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 @@ -1397,7 +1404,6 @@ 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 */ FUNC_ENTER_API(FAIL) @@ -1430,32 +1436,12 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) 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))) + if((ret_value = H5VL_file_create(filename, flags, fcpl_id, fapl_id)) < 0) 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; - 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() */ @@ -1503,8 +1489,7 @@ 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 */ + hid_t ret_value; /*return value */ FUNC_ENTER_API(FAIL) H5TRACE3("i", "*sIui", filename, flags, fapl_id); @@ -1523,20 +1508,10 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) 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))) + if((ret_value = H5VL_file_open(filename, flags, fapl_id))<0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open 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 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() */ @@ -1558,103 +1533,13 @@ 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 */ 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 */ + if((ret_value = H5VL_file_flush(object_id, scope)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") done: FUNC_LEAVE_API(ret_value) @@ -1743,7 +1628,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5F_close(H5F_t *f) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1914,10 +1799,10 @@ H5F_try_close(H5F_t *f) /* Check if this is a child file in a mounting hierarchy & proceed up the * hierarchy if so. */ - if(f->parent) + 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") @@ -1970,37 +1855,14 @@ done: herr_t H5Fclose(hid_t file_id) { - H5F_t *f = NULL; - int nref; 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") - - /* 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))) - 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 */ + if((ret_value = H5VL_file_close(file_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") done: FUNC_LEAVE_API(ret_value) @@ -2030,15 +1892,24 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Freopen(hid_t file_id) +H5Freopen(hid_t uid) { H5F_t *old_file = NULL; H5F_t *new_file = NULL; - hid_t ret_value; + H5VL_id_wrapper_t *id_wrapper, *new_id_wrapper; + hid_t file_id, new_file_id, ret_value; FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", file_id); + /* Get the file */ + if(H5I_FILE_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + file_id = id_wrapper->obj_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") @@ -2054,11 +1925,22 @@ H5Freopen(hid_t file_id) new_file->open_name = H5MM_xstrdup(old_file->open_name); new_file->actual_name = H5MM_xstrdup(old_file->actual_name); - if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) + if((new_file_id = H5I_register(H5I_FILE, new_file, 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; + new_file->file_id = new_file_id; + +#if 1 /*MSC - This needs to go through the VOL */ + if(NULL == (new_id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + new_id_wrapper->obj_id = new_file_id; + new_id_wrapper->vol_plugin = id_wrapper->vol_plugin; + new_id_wrapper->vol_plugin->nrefs ++; + + if((ret_value = H5I_register(H5I_FILE_PUBLIC, new_id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") +#endif done: if(ret_value < 0 && new_file) @@ -2083,30 +1965,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_intent(hid_t file_id, unsigned *intent_flags) +H5Fget_intent(hid_t uid, unsigned *intent_flags) { herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*Iu", file_id, intent_flags); + H5TRACE2("e", "i*Iu", uid, 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 */ + if((ret_value = H5VL_file_get(uid, H5VL_FILE_GET_INTENT, intent_flags)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file intent") + } done: FUNC_LEAVE_API(ret_value) @@ -2136,13 +2006,28 @@ H5F_get_id(H5F_t *file, hbool_t app_ref) HDassert(file); if(file->file_id == -1) { + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ /* 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") + + /* Create a new id that points to a struct that holds the file id and the VOL id */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper->obj_id = file->file_id; + id_wrapper->vol_plugin = file->vol_cls; + id_wrapper->vol_plugin->nrefs ++; + + if((H5I_register(H5I_FILE_PUBLIC, id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") } 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") + + /* Increment reference count on upper level ID. */ + if(H5VL_inc_ref_uid(file->file_id, app_ref) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing user ID failed") } /* end else */ ret_value = file->file_id; @@ -2502,24 +2387,15 @@ 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) +H5Fget_freespace(hid_t uid) { - H5F_t *file; /* File object for file ID */ - hsize_t tot_space; /* Amount of free space in the file */ hssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE1("Hs", "i", file_id); + H5TRACE1("Hs", "i", uid); - /* 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") - - /* 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") - - ret_value = (hssize_t)tot_space; + if(H5VL_file_get(uid, H5VL_FILE_GET_FREE_SPACE, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file free space") done: FUNC_LEAVE_API(ret_value) @@ -2545,24 +2421,15 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_filesize(hid_t file_id, hsize_t *size) +H5Fget_filesize(hid_t uid, hsize_t *size) { - H5F_t *file; /* File object for file ID */ - haddr_t eof; /* End of file address */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*h", file_id, size); + H5TRACE2("e", "i*h", uid, 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") - - /* 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") - - *size = (hsize_t)eof; + if((ret_value = H5VL_file_get(uid, H5VL_FILE_GET_SIZE, size)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file size") done: FUNC_LEAVE_API(ret_value) @@ -2721,23 +2588,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) +H5Fget_mdc_config(hid_t uid, H5AC_cache_config_t *config_ptr) { - H5F_t *file; /* File object for file ID */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*x", file_id, config_ptr); + H5TRACE2("e", "i*x", uid, 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.") + if((ret_value = H5VL_file_get(uid, H5VL_FILE_GET_MDC_CONF, config_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get mdc config") done: FUNC_LEAVE_API(ret_value) @@ -2760,16 +2623,22 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) +H5Fset_mdc_config(hid_t uid, H5AC_cache_config_t *config_ptr) { H5F_t *file; /* File object for file ID */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*x", file_id, config_ptr); + H5TRACE2("e", "i*x", uid, config_ptr); + + if(H5I_FILE_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = (H5F_t *)H5I_object_verify(id_wrapper->obj_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* set the resize configuration */ @@ -2798,24 +2667,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate_ptr) +H5Fget_mdc_hit_rate(hid_t uid, double *hit_rate_ptr) { - H5F_t *file; /* File object for file ID */ 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") + H5TRACE2("e", "i*d", uid, hit_rate_ptr); 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.") + if((ret_value = H5VL_file_get(uid, H5VL_FILE_GET_MDC_HR, hit_rate_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get MDC hit rate") done: FUNC_LEAVE_API(ret_value) @@ -2840,28 +2703,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_mdc_size(hid_t file_id, size_t *max_size_ptr, size_t *min_clean_size_ptr, +H5Fget_mdc_size(hid_t uid, 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; 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, + H5TRACE5("e", "i*z*z*z*Is", uid, 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") - - /* 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.") - - if(cur_num_entries_ptr != NULL) - *cur_num_entries_ptr = (int)cur_num_entries; + if((ret_value = H5VL_file_get(uid, H5VL_FILE_GET_MDC_SIZE, 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 hit rate") done: FUNC_LEAVE_API(ret_value) @@ -2889,16 +2742,22 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Freset_mdc_hit_rate_stats(hid_t file_id) +H5Freset_mdc_hit_rate_stats(hid_t uid) { H5F_t *file; /* File object for file ID */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", file_id); + H5TRACE1("e", "i", uid); + + if(H5I_FILE_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = (H5F_t *)H5I_object_verify(id_wrapper->obj_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Reset the hit rate statistic */ @@ -2933,43 +2792,51 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size) +H5Fget_name(hid_t uid, char *name/*out*/, size_t size) { - H5F_t *f; /* Top file in mount hierarchy */ - size_t len; ssize_t ret_value; 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 */ + H5TRACE3("Zs", "ixz", uid, name, size); + + /* MSC - temp fix to handle later when all user level ids are of type UID */ + if (H5I_FILE_PUBLIC == H5I_get_type(uid) || H5I_GROUP_PUBLIC == H5I_get_type(uid) || + H5I_DATATYPE_PUBLIC == H5I_get_type(uid) || H5I_DATASET_PUBLIC == H5I_get_type(uid) || + H5I_ATTR_PUBLIC == H5I_get_type(uid)) { + if(H5VL_file_get(uid, H5VL_FILE_GET_NAME, name, &ret_value, size) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file name") + } 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 */ + H5F_t *f; /* Top file in mount hierarchy */ + size_t len; + /* 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(uid) == H5I_FILE ) { + if(NULL == (f = (H5F_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + } /* end if */ + else { + H5G_loc_t loc; /* Object location */ - len = HDstrlen(H5F_OPEN_NAME(f)); + /* Get symbol table entry */ + if(H5G_loc(uid, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID") + f = loc.oloc->file; + } /* end else */ - if(name) { - HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size)); - if(len >= size) - name[size-1]='\0'; - } /* end if */ + len = HDstrlen(H5F_OPEN_NAME(f)); - /* Set return value */ - ret_value = (ssize_t)len; + if(name) { + HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size)); + if(len >= size) + name[size-1]='\0'; + } /* end if */ + /* Set return value */ + ret_value = (ssize_t)len; + } done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_name() */ @@ -2993,57 +2860,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) +H5Fget_info2(hid_t uid, H5F_info2_t *finfo) { - H5F_t *f; /* Top file in mount hierarchy */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*x", obj_id, finfo); + H5TRACE2("e", "i*x", uid, finfo); /* Check args */ 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") - - /* 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; - + if((ret_value = H5VL_file_get(uid, H5VL_FILE_GET_INFO, finfo)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file info") done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_info2() */ @@ -3065,25 +2894,21 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, +H5Fget_free_sections(hid_t uid, 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 */ FUNC_ENTER_API(FAIL) - H5TRACE4("Zs", "iFmzx", file_id, type, nsects, sect_info); + H5TRACE4("Zs", "iFmzx", uid, 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") - + if(H5VL_file_get(uid, H5VL_FILE_GET_FREE_SECTIONS, sect_info, &ret_value, + type, nsects) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file info") done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_free_sections() */ @@ -3104,16 +2929,22 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fclear_elink_file_cache(hid_t file_id) +H5Fclear_elink_file_cache(hid_t uid) { H5F_t *file; /* File */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", file_id); + H5TRACE1("e", "i", uid); /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + if(H5I_FILE_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == (file = (H5F_t *)H5I_object_verify(id_wrapper->obj_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Release the EFC */ @@ -3270,4 +3101,3 @@ H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_store_msg_crt_idx() */ - diff --git a/src/H5Fefc.c b/src/H5Fefc.c index 08d27a1..11ecbc1 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 @@ -156,6 +157,16 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, HDassert(parent->shared); HDassert(name); +#if 0 + /* 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_ID_NAME, &vol_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID") + if(NULL == (vol_plugin = (H5VL_class_t *)H5I_object(vol_id))) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, NULL, "invalid vol plugin ID in file access property list") +#endif + /* Get external file cache */ efc = parent->shared->efc; @@ -163,10 +174,23 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, * support this so clients do not have to make 2 different calls depending * on the state of the efc. */ if(!efc) { +#if 1 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") - +#endif +#if 0 + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->file_cls.open)(name, flags, fcpl_id, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + ret_value->vol_id = vol_id; + /* increment the ref count on the vol ID */ + if(H5I_inc_ref(ret_value->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") +#endif /* Increment the number of open objects to prevent the file from being * closed out from under us - "simulate" having an open file id. Note * that this behaviour replaces the calls to H5F_incr_nopen_objs() and @@ -236,10 +260,23 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, } /* end if */ else { /* Cannot cache file, just open file and return */ +#if 1 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") - +#endif +#if 0 + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->file_cls.open)(name, flags, fcpl_id, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + ret_value->vol_id = vol_id; + /* increment the ref count on the vol ID */ + if(H5I_inc_ref(ret_value->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") +#endif /* Increment the number of open objects to prevent the file from * being closed out from under us - "simulate" having an open * file id */ @@ -256,11 +293,24 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, /* Build new entry */ if(NULL == (ent->name = H5MM_strdup(name))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - +#if 1 /* 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") +#endif +#if 0 + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ent->file = (vol_plugin->file_cls.open)(name, flags, fcpl_id, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + ent->file->vol_id = vol_id; + /* increment the ref count on the vol ID */ + if(H5I_inc_ref(ent->file->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") +#endif open_file = TRUE; /* Increment the number of open objects to prevent the file from being diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 334879c..bdc01a6 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 */ @@ -274,6 +275,7 @@ struct H5F_t { 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 */ + struct H5VL_class_t *vol_cls; /* class of the VOL plugin */ }; diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 40e075b..7e45cfa 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -40,7 +40,6 @@ typedef struct H5F_file_t H5F_file_t; /* Block aggregation structure */ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; - /* * Encode and decode macros for file meta-data. * Currently, all file meta-data is little-endian. @@ -408,6 +407,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_ACS_SDATA_BLOCK_SIZE_NAME "sdata_block_size" /* Minimum "small data" allocation block size (when aggregating "small" raw data allocations) */ #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_VOL_NAME "vol_cls" /* File VOL plugin */ #define H5F_ACS_FILE_DRV_INFO_NAME "driver_info" /* File driver 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 */ @@ -508,10 +508,12 @@ 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); /* Functions than retrieve values from the file struct */ @@ -531,6 +533,7 @@ H5_DLL hid_t H5F_get_access_plist(H5F_t *f, hbool_t app_ref); H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref); H5_DLL herr_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr); H5_DLL 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); +H5_DLL struct H5VL_class_t *H5F_get_vol_cls(const H5F_t *f); /* Functions than retrieve values set/cached from the superblock/FCPL */ H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f); diff --git a/src/H5Fquery.c b/src/H5Fquery.c index c04ba24..c9b21ea 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -1073,3 +1073,24 @@ H5F_use_tmp_space(const H5F_t *f) FUNC_LEAVE_NOAPI(f->shared->use_tmp_space) } /* end H5F_use_tmp_space() */ + +/*------------------------------------------------------------------------- + * Function: H5F_get_vol_cls + * + * Return: vol_cls on success/abort on failure (shouldn't fail) + * + * Programmer: Mohamad Chaarawi + * April 2012 + * + *------------------------------------------------------------------------- + */ +H5VL_class_t * +H5F_get_vol_cls(const H5F_t *f) +{ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + FUNC_LEAVE_NOAPI(f->vol_cls) +} /* end H5F_get_parent() */ diff --git a/src/H5Ftest.c b/src/H5Ftest.c index 73b00a6..7c15757 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 */ @@ -96,14 +96,25 @@ *------------------------------------------------------------------------- */ herr_t -H5F_get_sohm_mesg_count_test(hid_t file_id, unsigned type_id, +H5F_get_sohm_mesg_count_test(hid_t uid, unsigned type_id, size_t *mesg_count) { H5F_t *file; /* File info */ + H5VL_id_wrapper_t *id_wrapper; + hid_t file_id; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + if (H5I_FILE_PUBLIC == H5I_get_type(uid)) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + file_id = id_wrapper->obj_id; + } + else { + file_id = uid; + } + /* Check arguments */ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") @@ -134,13 +145,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_check_cached_stab_test(hid_t file_id) +H5F_check_cached_stab_test(hid_t uid) { H5F_t *file; /* File info */ + H5VL_id_wrapper_t *id_wrapper; + hid_t file_id; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + if (H5I_FILE_PUBLIC == H5I_get_type(uid)) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + file_id = id_wrapper->obj_id; + } + else { + file_id = uid; + } + /* Check arguments */ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") @@ -168,13 +190,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_get_maxaddr_test(hid_t file_id, haddr_t *maxaddr) +H5F_get_maxaddr_test(hid_t uid, haddr_t *maxaddr) { H5F_t *file; /* File info */ + H5VL_id_wrapper_t *id_wrapper; + hid_t file_id; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + if (H5I_FILE_PUBLIC == H5I_get_type(uid)) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + file_id = id_wrapper->obj_id; + } + else { + file_id = uid; + } + /* Check arguments */ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") @@ -94,7 +94,7 @@ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5Pprivate.h" /* Property lists */ - +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -261,19 +261,15 @@ 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 */ + 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") @@ -298,17 +294,18 @@ 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") -done: - if(ret_value < 0) - if(grp && H5G_close(grp) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") + if(H5P_set(plist, H5G_CRT_LCPL_ID_NAME, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id") + /* Create the group through the VOL */ + if((ret_value = H5VL_group_create(loc_id, name, gcpl_id, gapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Gcreate2() */ @@ -351,18 +348,11 @@ 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 */ 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; @@ -377,36 +367,11 @@ 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)); - - /* 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") + /* Create the group through the VOL */ + if((ret_value = H5VL_group_create(loc_id, NULL, gcpl_id, gapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") done: - /* 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, FAIL, "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, FAIL, "unable to decrement refcount on newly created object") - } /* end if */ - - /* Cleanup on failure */ - if(ret_value < 0) - if(grp && H5G_close(grp) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - FUNC_LEAVE_API(ret_value) } /* end H5Gcreate_anon() */ @@ -431,16 +396,12 @@ 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 */ 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") @@ -451,20 +412,11 @@ 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") - - /* 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") + /* Open the group through the VOL */ + if((ret_value = H5VL_group_open(loc_id, name, gapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open group") done: - if(ret_value < 0) { - if(grp && H5G_close(grp) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - } /* end if */ - FUNC_LEAVE_API(ret_value) } /* end H5Gopen2() */ @@ -486,86 +438,17 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Gget_create_plist(hid_t group_id) +H5Gget_create_plist(hid_t uid) { - 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; FUNC_ENTER_API(FAIL) - H5TRACE1("i", "i", group_id); + H5TRACE1("i", "i", uid); - /* 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") - - /* 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_gcpl_id; + if(H5VL_group_get(uid, H5VL_GROUP_GET_GCPL, &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() */ @@ -584,31 +467,36 @@ 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) { H5I_type_t id_type; /* Type of ID */ - H5G_loc_t loc; /* Location of group */ + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ 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); - if(!(H5I_GROUP == id_type || H5I_FILE == id_type)) + id_type = H5I_get_type(loc_id); + if(!(H5I_GROUP_PUBLIC == id_type || H5I_FILE_PUBLIC == 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 token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP, &location) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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(loc_id, H5VL_GROUP_GET_INFO, grp_info, location)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Gget_info() */ @@ -630,19 +518,14 @@ 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 */ + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ 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) @@ -653,24 +536,19 @@ 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); + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, name, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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; - - /* 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(loc_id, H5VL_GROUP_GET_INFO, grp_info, location)) < 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") - + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Gget_info_by_name() */ @@ -693,11 +571,8 @@ 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 */ + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -705,8 +580,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) @@ -721,25 +594,20 @@ 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); + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup(loc_id, H5VL_OBJECT_LOOKUP_BY_IDX, &location, group_name, + idx_type, order, n, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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") + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_group_get(loc_id, H5VL_GROUP_GET_INFO, grp_info, location)) < 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") - + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Gget_info_by_idx() */ @@ -765,16 +633,9 @@ H5Gclose(hid_t group_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", group_id); - /* Check args */ - if(NULL == H5I_object_verify(group_id,H5I_GROUP)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") - - /* - * Decrement the counter on the group atom. It will be freed if the count - * reaches zero. - */ - if(H5I_dec_app_ref(group_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") + /* Close the group through the VOL */ + if(H5VL_group_close(group_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 9473011..e5c419b 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 */ @@ -201,24 +201,22 @@ 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 */ 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,22 +242,23 @@ 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, H5G_CRT_LCPL_ID_NAME, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for lcpl id") + + /* Create the group through the VOL */ + if((ret_value = H5VL_group_create(loc_id, name, tmp_gcpl, H5P_GROUP_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") 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) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - FUNC_LEAVE_API(ret_value) } /* end H5Gcreate1() */ @@ -284,33 +283,20 @@ 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 */ 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") - - /* 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") + /* Open the group through the VOL */ + if((ret_value = H5VL_group_open(loc_id, name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") done: - if(ret_value < 0) { - if(grp && H5G_close(grp) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - } /* end if */ - FUNC_LEAVE_API(ret_value) } /* end H5Gopen1() */ diff --git a/src/H5Gint.c b/src/H5Gint.c index ad2e57e..ca60a6a 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -44,7 +44,8 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ - +#include "H5Pprivate.h" /* Property lists */ +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ @@ -107,7 +108,6 @@ H5FL_DEFINE(H5G_shared_t); /* Declare the free list to manage H5_obj_t's */ H5FL_DEFINE(H5_obj_t); - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -814,6 +814,7 @@ H5G_iterate(hid_t loc_id, const char *group_name, 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 */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure of new opend group*/ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -834,6 +835,16 @@ H5G_iterate(hid_t loc_id, const char *group_name, if((gid = H5I_register(H5I_GROUP, grp, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + /* MSC - Create a new id that points to a struct that holds the group id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper->obj_id = gid; + id_wrapper->vol_plugin = H5F_get_vol_cls(loc.oloc->file); + + if((gid = H5I_register(H5I_GROUP_PUBLIC, id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle") + /* Set up user data for callback */ udata.gid = gid; udata.lnk_op = *lnk_op; @@ -846,7 +857,7 @@ H5G_iterate(hid_t loc_id, const char *group_name, done: /* Release the group opened */ if(gid > 0) { - if(H5I_dec_app_ref(gid) < 0) + if(H5I_dec_app_ref(id_wrapper->obj_id) < 0 && H5I_dec_app_ref(gid) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") } /* end if */ else if(grp && H5G_close(grp) < 0) @@ -1084,6 +1095,7 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5G_loc_t loc; /* Location of group passed in */ H5G_loc_t start_loc; /* Location of starting group */ unsigned rc; /* Reference count of object */ + H5VL_id_wrapper_t *id_wrapper; /* wrapper for the group ID */ herr_t ret_value; /* Return value */ /* Portably clear udata struct (before FUNC_ENTER) */ @@ -1107,6 +1119,16 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type, if(H5G_loc(gid, &start_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + /* MSC - Create a new id that points to a struct that holds the group id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper->obj_id = gid; + id_wrapper->vol_plugin = H5F_get_vol_cls(loc.oloc->file); + + if((gid = H5I_register(H5I_GROUP_PUBLIC, id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle") + /* Set up user data */ udata.gid = gid; udata.curr_loc = &start_loc; @@ -1182,7 +1204,7 @@ done: /* Release the group opened */ if(gid > 0) { - if(H5I_dec_app_ref(gid) < 0) + if(H5I_dec_app_ref(id_wrapper->obj_id) < 0 && H5I_dec_app_ref(gid) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") } /* end if */ else if(grp && H5G_close(grp) < 0) @@ -1191,3 +1213,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..1080add 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 */ @@ -159,10 +159,25 @@ static herr_t H5G_loc_get_comment_cb(H5G_loc_t *grp_loc, const char *name, herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc) { + H5I_type_t id_type; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + id_type = H5I_get_type(loc_id); + /* get the actual ID from an upper ID level */ + /* MSC - this is a workaround to allow the test suite to pass and + at some point needs to be removed once all high level operations + that needs to go through the VOL actually go through the VOL*/ + if (H5I_FILE_PUBLIC == id_type || H5I_GROUP_PUBLIC == id_type || + H5I_DATASET_PUBLIC == id_type || H5I_DATATYPE_PUBLIC == id_type || + H5I_ATTR_PUBLIC == id_type) { + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + loc_id = id_wrapper->obj_id; + } + switch(H5I_get_type(loc_id)) { case H5I_FILE: { @@ -248,6 +263,7 @@ 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") diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index f765b52..680f2c5 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -98,6 +98,8 @@ H5G_CRT_GINFO_EST_NAME_LEN \ } +#define H5G_CRT_LCPL_ID_NAME "group_lcpl_id" + /* If the module using this macro is allowed access to the private variables, access them directly */ #ifdef H5G_PACKAGE #define H5G_MOUNTED(G) ((G)->shared->mounted) @@ -202,6 +204,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 */ diff --git a/src/H5Gtest.c b/src/H5Gtest.c index 48aa10b..86730a7 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 */ @@ -514,6 +515,7 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign { void *obj_ptr; /* Pointer to object for ID */ H5G_name_t *obj_path; /* Pointer to group hier. path for obj */ + H5I_type_t id_type; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -522,6 +524,20 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign HDassert(user_path_len); HDassert(obj_hidden); + id_type = H5I_get_type(obj_id); + /* get the actual OBJ_ID from an upper ID level */ + /* MSC - this is a workaround to allow the test suite to pass and + at some point needs to be removed once all high level operations + that needs to go through the VOL actually go through the VOL*/ + if (H5I_FILE_PUBLIC == id_type || H5I_GROUP_PUBLIC == id_type || + H5I_DATASET_PUBLIC == id_type || H5I_DATATYPE_PUBLIC == id_type || + H5I_ATTR_PUBLIC == id_type) { + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + obj_id = id_wrapper->obj_id; + } + /* Get pointer to object for ID */ if(NULL == (obj_ptr = H5I_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get object for ID") diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index aff87f8..6411175 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -45,7 +45,7 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Ppublic.h" /* Property Lists */ #include "H5WBprivate.h" /* Wrapped Buffers */ - +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ @@ -180,6 +180,7 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, hid_t lapl_id = (-1); /* LAPL local to this routine */ H5P_genplist_t *lapl; /* LAPL with nlinks set */ hid_t cur_grp = (-1); + H5VL_id_wrapper_t *id_wrapper; /* wrapper for the group ID */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -210,6 +211,16 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, if((cur_grp = H5I_register(H5I_GROUP, grp, FALSE)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "unable to register group") + /* MSC - Create a new id that points to a struct that holds the group id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper->obj_id = cur_grp; + id_wrapper->vol_plugin = H5F_get_vol_cls(grp_loc->oloc->file); + + if((cur_grp = H5I_register(H5I_GROUP_PUBLIC, id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle") + /* Check for generic default property list and use link access default if so */ if(_lapl_id == H5P_DEFAULT) { HDassert(H5P_LINK_ACCESS_DEFAULT != -1); @@ -280,7 +291,7 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, done: /* Close location given to callback. */ - if(cur_grp > 0 && H5I_dec_ref(cur_grp) < 0) + if(cur_grp > 0 && H5I_dec_ref(id_wrapper->obj_id) < 0 && H5I_dec_ref(cur_grp) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location") if(ret_value < 0 && cb_return > 0 && H5I_dec_ref(cb_return) < 0) @@ -48,6 +48,7 @@ #include "H5Ipkg.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* Object headers */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /* Define this to compile in support for dumping ID information */ /* #define H5I_DEBUG_OUTPUT */ @@ -155,6 +156,7 @@ H5I_init_interface(void) { FUNC_ENTER_NOAPI_NOINIT_NOERR +done: FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5I_init_interface() */ @@ -1016,12 +1018,26 @@ void * H5I_object_verify(hid_t id, H5I_type_t id_type) { H5I_id_info_t *id_ptr = NULL; /*ptr to the new atom */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ void *ret_value = NULL; /*return value */ FUNC_ENTER_NOAPI(NULL) HDassert(id_type >= 1 && id_type < H5I_next_type); + /* Temp workaround for tests to pass */ +#if 1 + if ((H5I_FILE_PUBLIC == H5I_get_type(id) && H5I_FILE_PUBLIC != id_type) || + (H5I_GROUP_PUBLIC == H5I_get_type(id) && H5I_GROUP_PUBLIC != id_type) || + (H5I_DATATYPE_PUBLIC == H5I_get_type(id) && H5I_DATATYPE_PUBLIC != id_type) || + (H5I_DATASET_PUBLIC == H5I_get_type(id) && H5I_DATASET_PUBLIC != id_type) || + (H5I_ATTR_PUBLIC == H5I_get_type(id) && H5I_ATTR_PUBLIC != id_type)) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + id = id_wrapper->obj_id; + } +#endif + /* Verify that the type of the ID is correct & lookup the ID */ if(id_type == H5I_TYPE(id) && NULL != (id_ptr = H5I_find_id(id))) { /* Get the object pointer to return */ @@ -2038,6 +2054,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 */ @@ -2200,14 +2217,17 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Iget_file_id(hid_t obj_id) +H5Iget_file_id(hid_t id) { hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE1("i", "i", obj_id); + H5TRACE1("i", "i", id); - if((ret_value = H5I_get_file_id(obj_id, TRUE)) < 0) + if((ret_value = H5I_get_file_id(id, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID") + + if (H5VL_replace_with_uids (&ret_value, 1) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID") done: @@ -2233,21 +2253,41 @@ hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref) { H5I_type_t type; /* ID type */ + H5I_type_t id_type; hid_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + id_type = H5I_get_type(obj_id); + /* get the actual OBJ_ID from an upper ID level */ + /* MSC - this is a workaround to allow the test suite to pass and + at some point needs to be removed once all high level operations + that needs to go through the VOL actually go through the VOL*/ + if (H5I_FILE_PUBLIC == id_type || H5I_GROUP_PUBLIC == id_type || + H5I_DATASET_PUBLIC == id_type || H5I_DATATYPE_PUBLIC == id_type || + H5I_ATTR_PUBLIC == id_type) { + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + obj_id = id_wrapper->obj_id; + } + /* Get object type */ type = H5I_TYPE(obj_id); - if(type == H5I_FILE) { + if(H5I_FILE == type) { /* 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") + /* Increment reference count on upper level ID. */ + if(H5VL_inc_ref_uid(obj_id, app_ref) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing user 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) { + 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 */ @@ -2267,6 +2307,160 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL_replace_with_uids + * + * Purpose: change the ids used by the HDF5 libraries to the UIDs that + * are provided to the user + * + * Return: How many IDs were replaced. + * + * Programmer: Mohamad Chaarawi + * Feb 2012 + * + *------------------------------------------------------------------------- + */ +int +H5VL_replace_with_uids(hid_t *old_list, ssize_t num_ids) +{ + ssize_t j; + H5I_type_t type; + int ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + for (j=0 ; j<num_ids ; j++) { + H5I_id_type_t *type_ptr; /*ptr to the type */ + hbool_t replaced = FALSE; + + type = H5I_get_type(old_list[j]); + + if (H5I_FILE == type) { + type_ptr = H5I_id_type_list_g[H5I_FILE_PUBLIC]; + } + else if (H5I_GROUP == type) { + type_ptr = H5I_id_type_list_g[H5I_GROUP_PUBLIC]; + } + else if (H5I_DATASET == type) { + type_ptr = H5I_id_type_list_g[H5I_DATASET_PUBLIC]; + } + else if (H5I_DATATYPE == type) { + type_ptr = H5I_id_type_list_g[H5I_DATATYPE_PUBLIC]; + } + else if (H5I_ATTR == type) { + type_ptr = H5I_id_type_list_g[H5I_ATTR_PUBLIC]; + } + else { + ret_value ++; + continue; + } + + 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 */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + unsigned i; /*counter */ + + /* Start at the beginning of the array */ + for(i = 0; i < type_ptr->hash_size; i++) { + id_ptr = type_ptr->id_list[i]; + while(id_ptr) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(id_ptr->id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + if (id_wrapper->obj_id == old_list[j]) { + old_list[j] = id_ptr->id; + ret_value ++; + replaced = TRUE; + break; + } + id_ptr = id_ptr->next; + } /* end while */ + if (replaced) + break; + } /* end for */ + } /* end if */ + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_replace_with_uids() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_inc_ref_uid + * + * Purpose: increment the ref count on the high level ID given the low level ID + * + * Return: How many IDs were replaced. + * + * Programmer: Mohamad Chaarawi + * Feb 2012 + * + *------------------------------------------------------------------------- + */ +int +H5VL_inc_ref_uid(hid_t id, hbool_t app_ref) +{ + H5I_id_type_t *type_ptr; /*ptr to the type */ + H5I_type_t type; + int ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + type = H5I_get_type(id); + + if (H5I_FILE == type) { + type_ptr = H5I_id_type_list_g[H5I_FILE_PUBLIC]; + } + else if (H5I_GROUP == type) { + type_ptr = H5I_id_type_list_g[H5I_GROUP_PUBLIC]; + } + else if (H5I_DATASET == type) { + type_ptr = H5I_id_type_list_g[H5I_DATASET_PUBLIC]; + } + else if (H5I_DATATYPE == type) { + type_ptr = H5I_id_type_list_g[H5I_DATATYPE_PUBLIC]; + } + else if (H5I_ATTR == type) { + type_ptr = H5I_id_type_list_g[H5I_ATTR_PUBLIC]; + } + else { + HGOTO_DONE(ret_value) + } + + 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 */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + unsigned i; /*counter */ + + /* Start at the beginning of the array */ + for(i = 0; i < type_ptr->hash_size; i++) { + id_ptr = type_ptr->id_list[i]; + while(id_ptr) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(id_ptr->id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + if (id_wrapper->obj_id == id) { + /* Increment reference count on atom. */ + if((ret_value = H5I_inc_ref(id_ptr->id, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") + HGOTO_DONE(ret_value) + } + id_ptr = id_ptr->next; + } /* end while */ + } /* end for */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_inc_ref_uid() */ + + +/*------------------------------------------------------------------------- * Function: H5I_debug * * Purpose: Dump the contents of a type to stderr for debugging. diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index bc0ef41..ee938df 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -24,25 +24,33 @@ /* 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 */ /* Macro to determine if a H5I_type_t is a "library type" */ #define H5I_IS_LIB_TYPE( type ) (type > 0 && type < H5I_NTYPES) /* Default sizes of the hash-tables for various atom types */ #define H5I_ERRSTACK_HASHSIZE 64 -#define H5I_FILEID_HASHSIZE 64 +#define H5I_FILEID_HASHSIZE 64 #define H5I_TEMPID_HASHSIZE 64 #define H5I_DATATYPEID_HASHSIZE 64 #define H5I_DATASPACEID_HASHSIZE 64 #define H5I_DATASETID_HASHSIZE 64 #define H5I_OID_HASHSIZE 64 -#define H5I_GROUPID_HASHSIZE 64 +#define H5I_GROUPID_HASHSIZE 64 #define H5I_ATTRID_HASHSIZE 64 #define H5I_REFID_HASHSIZE 64 #define H5I_VFL_HASHSIZE 64 +#define H5I_VOL_HASHSIZE 64 +#define H5I_FILE_PUBLIC_HASHSIZE 64 +#define H5I_GROUP_PUBLIC_HASHSIZE 64 +#define H5I_DATASET_PUBLIC_HASHSIZE 64 +#define H5I_ATTR_PUBLIC_HASHSIZE 64 +#define H5I_DATATYPE_PUBLIC_HASHSIZE 64 #define H5I_GENPROPCLS_HASHSIZE 64 #define H5I_GENPROPOBJ_HASHSIZE 128 #define H5I_ERRCLS_HASHSIZE 64 @@ -71,6 +79,5 @@ 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); - #endif /* _H5Iprivate_H */ diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index d630556..1673f60 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -36,14 +36,20 @@ 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_FILE_PUBLIC, /*type ID for upper level file ID objects */ + H5I_GROUP_PUBLIC, /*type ID for upper level group ID objects */ + H5I_DATASET_PUBLIC, /*type ID for upper level dataset ID objects */ + H5I_ATTR_PUBLIC, /*type ID for upper level attribute ID objects */ + H5I_DATATYPE_PUBLIC, /*type ID for upper level datatype ID objects */ 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 */ @@ -36,6 +36,7 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* File objects */ #include "H5Pprivate.h" /* Property lists */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -313,8 +314,6 @@ herr_t H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t lcpl_id, hid_t lapl_id) { - H5G_loc_t src_loc, *src_loc_p; - H5G_loc_t dst_loc, *dst_loc_p; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -324,10 +323,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 +330,10 @@ 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; - - /* 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") + /* Create the link through the VOL */ + if((ret_value = H5VL_link_move(src_loc_id, src_name, dst_loc_id, dst_name, + FALSE, lcpl_id, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -371,8 +358,6 @@ herr_t H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t lcpl_id, hid_t lapl_id) { - H5G_loc_t src_loc, *src_loc_p; - H5G_loc_t dst_loc, *dst_loc_p; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -382,10 +367,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,18 +374,10 @@ 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") + /* Create the link through the VOL */ + if((ret_value = H5VL_link_move(src_loc_id, src_name, dst_loc_id, dst_name, + TRUE, lcpl_id, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -433,15 +406,15 @@ 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 */ + 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 +422,22 @@ 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; + + /* 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, H5L_CRT_TARGET_NAME_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_CREATE_SOFT_LINK, link_loc_id, link_name, + lcpl_id, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -478,8 +464,7 @@ 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; + H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -489,10 +474,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 +481,24 @@ 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 group access property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_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") + /* 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, H5L_CRT_TARGET_ID_NAME, &cur_loc_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id") + if(H5P_set(plist, H5L_CRT_TARGET_NAME_NAME, &cur_name) < 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_CREATE_HARD_LINK, new_loc_id, new_name, + lcpl_id, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -548,7 +533,7 @@ 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; + H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -556,16 +541,31 @@ 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; + + /* 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, H5L_CRT_LINK_TYPE_NAME, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5L_CRT_UDATA_NAME, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5L_CRT_UDATA_SIZE_NAME, &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_CREATE_UD_LINK, link_loc_id, link_name, + lcpl_id, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -592,21 +592,18 @@ done: herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id) { - H5G_loc_t loc; /* Group's location */ 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") + /* Delete the link through the VOL */ + if((ret_value = H5VL_link_delete(loc_id, name, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -667,7 +664,36 @@ H5Ldelete_by_idx(hid_t loc_id, const char *group_name, /* 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") +#if 0 + H5L_trav_rmbi_t udata; /* User data for callback */ + 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(!group_name || !*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + else + 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; + /* Delete the link through the VOL */ + if((ret_value = H5VL_link_delete(loc_id, group_name, H5L_delete_by_idx_cb, &udata, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") +#endif done: FUNC_LEAVE_API(ret_value) } /* end H5Ldelete_by_idx() */ @@ -1147,7 +1173,7 @@ 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) { H5I_type_t id_type; /* Type of ID */ @@ -1157,11 +1183,28 @@ H5Literate(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, 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); - if(!(H5I_GROUP == id_type || H5I_FILE == id_type)) + id_type = H5I_get_type(id); + +#if 0 + /* get the actual ID from an upper ID level */ + /* MSC - this is a workaround to allow the test suite to pass and + at some point needs to be removed once all high level operations + that needs to go through the VOL actually go through the VOL*/ + if (H5I_FILE_PUBLIC == id_type || H5I_GROUP_PUBLIC == id_type) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + grp_id = id_wrapper->obj_id; + id_type = H5I_get_type(grp_id); + } + else { + grp_id = id; + } +#endif + + if(!(H5I_GROUP_PUBLIC == id_type || H5I_FILE_PUBLIC == id_type)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") @@ -1179,7 +1222,7 @@ H5Literate(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, lnk_op.op_func.op_new = op; /* 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) + if((ret_value = H5G_iterate(id, ".", idx_type, order, idx, &last_lnk, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") /* Set the index we stopped at */ @@ -1301,9 +1344,22 @@ H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, 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); - if(!(H5I_GROUP == id_type || H5I_FILE == id_type)) + +#if 0 + if (H5I_FILE_PUBLIC == id_type) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + grp_id = id_wrapper->obj_id; + id_type = H5I_get_type(grp_id); + } + else { + grp_id = uid; + } +#endif + + /* Check args */ + if(!(H5I_GROUP_PUBLIC == id_type || H5I_FILE_PUBLIC == id_type)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") @@ -1664,6 +1720,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED H5G_loc_t temp_loc; /* For UD callback */ hbool_t temp_loc_init = FALSE; /* Temporary location for UD callback (temp_loc) has been initialized */ hbool_t obj_created = FALSE; /* Whether an object was created (through a hard link) */ + H5VL_id_wrapper_t *id_wrapper; /* wrapper for the group ID */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1758,6 +1815,16 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED if((grp_id = H5I_register(H5I_GROUP, grp, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register ID for group") + /* MSC - Create a new id that points to a struct that holds the group id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper->obj_id = grp_id; + id_wrapper->vol_plugin = H5F_get_vol_cls(grp_loc->oloc->file); + + if((grp_id = H5I_register(H5I_GROUP_PUBLIC, id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle") + /* Make callback */ if((link_class->create_func)(name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size, H5P_DEFAULT) < 0) HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "link creation callback failed") @@ -1781,7 +1848,7 @@ done: /* Close the location given to the user callback if it was created */ if(grp_id >= 0) { - if(H5I_dec_app_ref(grp_id) < 0) + if(H5I_dec_app_ref(id_wrapper->obj_id) < 0 && H5I_dec_app_ref(grp_id) < 0) HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback") } /* end if */ else if(grp != NULL) { @@ -2340,6 +2407,7 @@ H5L_delete(H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) /* Set up user data for unlink operation */ udata.dxpl_id = dxpl_id; + if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, H5L_delete_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, FAIL, "can't unlink object") diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 62e7a5e..c57edd9 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -544,6 +544,8 @@ H5Lcreate_external(const char *file_name, const char *obj_name, void *ext_link_buf = NULL; /* Buffer to contain external link */ size_t buf_size; /* Size of buffer to hold external link */ uint8_t *p; /* Pointer into external link buffer */ + H5P_genplist_t *plist; /* Property list pointer */ + H5L_type_t link_type = H5L_TYPE_EXTERNAL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -560,6 +562,10 @@ H5Lcreate_external(const char *file_name, const char *obj_name, 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") @@ -576,9 +582,22 @@ H5Lcreate_external(const char *file_name, const char *obj_name, p += HDstrlen(file_name) + 1; HDstrcpy((char *)p, norm_obj_name); /* 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") + /* 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, H5L_CRT_LINK_TYPE_NAME, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5L_CRT_UDATA_NAME, &ext_link_buf) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5L_CRT_UDATA_SIZE_NAME, &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_CREATE_UD_LINK, link_loc_id, link_name, + lcpl_id, lapl_id)) < 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..70a5d76 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -37,6 +37,11 @@ /* ======== Link creation property names ======== */ #define H5L_CRT_INTERMEDIATE_GROUP_NAME "intermediate_group" /* Create intermediate groups flag */ +#define H5L_CRT_TARGET_ID_NAME "target location id" +#define H5L_CRT_TARGET_NAME_NAME "target name" +#define H5L_CRT_LINK_TYPE_NAME "link type" +#define H5L_CRT_UDATA_NAME "udata" +#define H5L_CRT_UDATA_SIZE_NAME "udata size" /* ======== Link access property names ======== */ #define H5L_ACS_NLINKS_NAME "max soft links" /* Number of soft links to traverse */ @@ -46,7 +46,7 @@ #include "H5MFprivate.h" /* File memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared object header messages */ - +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -230,23 +230,30 @@ H5O_init_interface(void) hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id) { - H5G_loc_t loc; hid_t ret_value = FAIL; + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ 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") + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, name, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") + + /* Open the object through the VOL */ + if((ret_value = H5VL_object_open_by_loc(loc_id, location, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") done: + if (NULL != location) { + free (location); + location = NULL; + } + FUNC_LEAVE_API(ret_value) } /* end H5Oopen() */ @@ -278,19 +285,13 @@ 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 *location = NULL; 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 +304,20 @@ 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); - - /* 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 token for the Object location through the VOL */ + if(H5VL_object_lookup(loc_id, H5VL_OBJECT_LOOKUP_BY_IDX, &location, group_name, + idx_type, order, n, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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((ret_value = H5VL_object_open_by_loc(loc_id, location, lapl_id)) < 0) + 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 (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Oopen_by_idx() */ @@ -365,36 +360,26 @@ 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 *location = NULL; 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") - - /* 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 token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_ADDR, &location, addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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((ret_value = H5VL_object_open_by_loc(loc_id, location, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") done: - + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Oopen_by_addr() */ @@ -424,20 +409,16 @@ 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 */ + H5P_genplist_t *plist; /* Property list pointer */ + char *name = NULL; + 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 +429,24 @@ 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; + + /* 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, H5L_CRT_TARGET_ID_NAME, &obj_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id") + if(H5P_set(plist, H5L_CRT_TARGET_NAME_NAME, &name) < 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_CREATE_HARD_LINK, new_loc_id, new_name, + lcpl_id, lapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -597,23 +593,30 @@ done: herr_t H5Oget_info(hid_t loc_id, H5O_info_t *oinfo) { - H5G_loc_t loc; /* Location of group */ + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ 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") + /* Get the token for the Object location through the VOL + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP, &location) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") + */ + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_object_get(loc_id, H5VL_OBJECT_GET_INFO, oinfo, NULL)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Oget_info() */ @@ -634,13 +637,52 @@ 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 */ +#if 1 + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ 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(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + if(!oinfo) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + else + 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 token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, name, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") + + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_object_get(loc_id, H5VL_OBJECT_GET_INFO, oinfo, location)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") + +done: + if (NULL != location) { + free (location); + location = NULL; + } + FUNC_LEAVE_API(ret_value) +#endif +#if 0 + 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 */ + 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) @@ -653,12 +695,30 @@ 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) + + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* 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") + 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") + /* Retrieve the object's information + if(H5G_loc_info(&loc, name, TRUE, oinfo, lapl_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + */ 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) +#endif } /* end H5Oget_info_by_name() */ @@ -680,11 +740,8 @@ 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 *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -692,8 +749,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 +763,20 @@ 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; + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup(loc_id, H5VL_OBJECT_LOOKUP_BY_IDX, &location, group_name, + idx_type, order, n, lapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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") + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_object_get(loc_id, H5VL_OBJECT_GET_INFO, oinfo, location)) < 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") - + if (NULL != location) { + free (location); + location = NULL; + } FUNC_LEAVE_API(ret_value) } /* end H5Oget_info_by_idx() */ @@ -834,21 +884,16 @@ 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 */ 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") - - /* 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") + if(H5VL_object_get(loc_id, H5VL_OBJECT_GET_COMMENT, &ret_value, comment, bufsize, + ".", H5P_LINK_ACCESS_DEFAULT) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object info") done: FUNC_LEAVE_API(ret_value) @@ -875,15 +920,12 @@ 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 */ 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 +934,9 @@ 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") + if(H5VL_object_get(loc_id, H5VL_OBJECT_GET_COMMENT, &ret_value, comment, bufsize, + name, lapl_id) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object info") done: FUNC_LEAVE_API(ret_value) @@ -1051,34 +1093,9 @@ H5Oclose(hid_t object_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", object_id); - /* Get the type of the object and close it in the correct way */ - switch(H5I_get_type(object_id)) { - case H5I_GROUP: - case H5I_DATATYPE: - case H5I_DATASET: - if(H5I_object(object_id) == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object") - if(H5I_dec_app_ref(object_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close 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_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)") - break; - } /* end switch */ + /* Close the object through the VOL */ + if(H5VL_object_close(object_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") done: FUNC_LEAVE_API(ret_value) @@ -1456,10 +1473,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) @@ -2445,12 +2463,31 @@ done: *------------------------------------------------------------------------- */ H5O_loc_t * -H5O_get_loc(hid_t object_id) +H5O_get_loc(hid_t id) { + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + hid_t object_id; + H5I_type_t id_type; H5O_loc_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + id_type = H5I_get_type(id); + + /* get the actual ID from an upper ID level */ + /* MSC - this is a workaround to allow the test suite to pass and + at some point needs to be removed once all high level operations + that needs to go through the VOL actually go through the VOL*/ + if (H5I_GROUP_PUBLIC == id_type || H5I_DATASET_PUBLIC == id_type || + H5I_DATATYPE_PUBLIC == id_type) { + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, NULL, "invalid user identifier") + object_id = id_wrapper->obj_id; + } + else { + object_id = id; + } + switch(H5I_get_type(object_id)) { case H5I_GROUP: if(NULL == (ret_value = H5O_OBJ_GROUP->get_oloc(object_id))) @@ -2474,6 +2511,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: diff --git a/src/H5Olink.c b/src/H5Olink.c index 88c9e28..12171b2 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -636,19 +636,26 @@ H5O_link_delete(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, void *_mesg) /* Check for delete callback */ if(link_class->del_func) { hid_t file_id; /* ID for the file the link is located in (passed to user callback) */ + hid_t wrapper_id; /* Get a file ID for the file the link is in */ if((file_id = H5F_get_id(f, FALSE)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get file ID") + wrapper_id = file_id; + + if (H5VL_replace_with_uids (&wrapper_id, 1) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID") + /* Call user-defined link's 'delete' callback */ - if((link_class->del_func)(lnk->name, file_id, lnk->u.ud.udata, lnk->u.ud.size) < 0) { + if((link_class->del_func)(lnk->name, wrapper_id, lnk->u.ud.udata, lnk->u.ud.size) < 0) { H5I_dec_ref(file_id); + H5I_dec_ref(wrapper_id); HGOTO_ERROR(H5E_OHDR, H5E_CALLBACK, FAIL, "link deletion callback returned failure") } /* end if */ /* Release the file ID */ - if(H5I_dec_ref(file_id) < 0) + if(H5I_dec_ref(file_id) < 0 && H5I_dec_ref(wrapper_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "can't close file") } /* end if */ } /* end if */ diff --git a/src/H5Pacpl.c b/src/H5Pacpl.c index 41a4f96..bd4a758 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 UDATA */ +#define H5A_CRT_LOCATION_SIZE sizeof(void *) +#define H5A_CRT_LOCATION_DEF NULL /******************/ /* Local Typedefs */ @@ -55,7 +60,8 @@ /********************/ /* Local Prototypes */ /********************/ - +/* Property class callbacks */ +static herr_t H5P_acrt_reg_prop(H5P_genclass_t *pclass); /*********************/ /* Package Variables */ @@ -67,7 +73,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 */ @@ -82,3 +88,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; + void *location = 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, H5A_CRT_TYPE_ID_NAME, sizeof(hid_t), &type_id, + 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, H5A_CRT_SPACE_ID_NAME, sizeof(hid_t), &space_id, + 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, H5A_CRT_LOCATION_NAME, H5A_CRT_LOCATION_SIZE, &location, + 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 32793e6..0a41371 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -180,6 +180,9 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass) H5O_fill_t fill = H5D_CRT_FILL_VALUE_DEF; /* Default fill value */ unsigned alloc_time_state = H5D_CRT_ALLOC_TIME_STATE_DEF; /* Default allocation time state */ H5O_efl_t efl = H5D_CRT_EXT_FILE_LIST_DEF; /* Default external file list */ + 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_NOAPI_NOINIT @@ -200,6 +203,21 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass) if(H5P_register_real(pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &efl, NULL, NULL, NULL, 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, H5D_CRT_TYPE_ID_NAME, sizeof(hid_t), &type_id, + 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, H5D_CRT_SPACE_ID_NAME, sizeof(hid_t), &space_id, + 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, H5D_CRT_LCPL_ID_NAME, sizeof(hid_t), &lcpl_id, + 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 7f72c85..2d46ec7 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 */ /****************/ @@ -123,6 +126,11 @@ /* Definition for external file cache size */ #define H5F_ACS_EFC_SIZE_SIZE sizeof(unsigned) #define H5F_ACS_EFC_SIZE_DEF 0 + +/* Definition for VOL plugin */ +#define H5F_ACS_VOL_SIZE sizeof(void *) +#define H5F_ACS_VOL_DEF H5VL_NATIVE + /* 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 @@ -130,7 +138,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 */ /******************/ @@ -226,6 +233,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) hbool_t latest_format = H5F_ACS_LATEST_FORMAT_DEF; /* Default setting for "use the latest version of the format" flag */ hbool_t want_posix_fd = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */ unsigned efc_size = H5F_ACS_EFC_SIZE_DEF; /* Default external file cache size */ + H5VL_class_t *vol_cls = H5F_ACS_VOL_DEF; /* Default VOL plugin */ H5FD_file_image_info_t file_image_info = H5F_ACS_FILE_IMAGE_INFO_DEF; /* Default file image info and callbacks */ herr_t ret_value = SUCCEED; /* Return value */ @@ -312,6 +320,10 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) if(H5P_register_real(pclass, H5F_ACS_EFC_SIZE_NAME, H5F_ACS_EFC_SIZE_SIZE, &efc_size, 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 ID */ + if(H5P_register_real(pclass, H5F_ACS_VOL_NAME, H5F_ACS_VOL_SIZE, &vol_cls, 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 */ if(H5P_register_real(pclass, H5F_ACS_FILE_IMAGE_INFO_NAME, H5F_ACS_FILE_IMAGE_INFO_SIZE, &file_image_info, NULL, NULL, NULL, H5F_ACS_FILE_IMAGE_INFO_DEL, H5F_ACS_FILE_IMAGE_INFO_COPY, NULL, H5F_ACS_FILE_IMAGE_INFO_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") @@ -342,6 +354,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; @@ -351,6 +364,14 @@ 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") + + /* Set the vol for the property list */ + if(H5VL_fapl_open(plist, vol_cls) < 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") @@ -392,28 +413,38 @@ 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) { + /* Set the vp; for the destination property list */ + if(H5VL_fapl_open(dst_plist, vol_cls) < 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 */ @@ -442,9 +473,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) @@ -452,6 +484,15 @@ 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) { + /* Close the driver for the property list */ + if(H5VL_fapl_close(vol_cls) < 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 */ @@ -2119,6 +2160,50 @@ done: /*------------------------------------------------------------------------- + * Function: H5P_set_vol + * + * Purpose: Set the file vol (VOL_ID) for a file access property list + * (PLIST_ID) and supply an optional struct containing the + * vol-specific properites (VOL_INFO). The vol properties will + * be copied into the property list and the reference count on + * the vol will be incremented, allowing the caller to close the + * vol ID but still use the property list. + * + * 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) +{ + H5VL_class_t *old_vol_cls; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* 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 ID") + + /* Close the vol for the property list */ + if(H5VL_fapl_close(old_vol_cls)<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)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set vol") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_set_vol() */ + + +/*------------------------------------------------------------------------- * Function: H5Pset_file_image * * Purpose: Sets the initial file image. Some file drivers can initialize @@ -2597,4 +2682,3 @@ H5P_file_image_info_close(const char UNUSED *name, size_t UNUSED size, void *val done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_file_image_info_close() */ - diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c index 983929d..eb35a6d 100644 --- a/src/H5Pgcpl.c +++ b/src/H5Pgcpl.c @@ -108,6 +108,7 @@ H5P_gcrt_reg_prop(H5P_genclass_t *pclass) { H5O_ginfo_t ginfo = H5G_CRT_GROUP_INFO_DEF; /* Default group info settings */ H5O_linfo_t linfo = H5G_CRT_LINK_INFO_DEF; /* Default link info settings */ + hid_t lcpl_id = H5P_LINK_CREATE_DEFAULT; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -120,6 +121,11 @@ H5P_gcrt_reg_prop(H5P_genclass_t *pclass) if(H5P_register_real(pclass, H5G_CRT_LINK_INFO_NAME, H5G_CRT_LINK_INFO_SIZE, &linfo, 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, H5G_CRT_LCPL_ID_NAME, sizeof(hid_t), &lcpl_id, + 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/H5Plcpl.c b/src/H5Plcpl.c index 60b4e37..ae701f2 100644 --- a/src/H5Plcpl.c +++ b/src/H5Plcpl.c @@ -49,6 +49,25 @@ #define H5L_CRT_INTERMEDIATE_GROUP_SIZE sizeof(unsigned) #define H5L_CRT_INTERMEDIATE_GROUP_DEF 0 +/* Definitions for target object ID */ +#define H5L_CRT_TARGET_ID_SIZE sizeof(hid_t) +#define H5L_CRT_TARGET_ID_DEF 0 + +/* 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 */ @@ -114,6 +133,11 @@ herr_t H5P_lcrt_reg_prop(H5P_genclass_t *pclass) { unsigned intmd_group = H5L_CRT_INTERMEDIATE_GROUP_DEF; /* Default setting for creating intermediate groups */ + hid_t target_id = H5L_CRT_TARGET_ID_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) @@ -122,6 +146,26 @@ H5P_lcrt_reg_prop(H5P_genclass_t *pclass) if(H5P_register_real(pclass, H5L_CRT_INTERMEDIATE_GROUP_NAME, H5L_CRT_INTERMEDIATE_GROUP_SIZE, &intmd_group, 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, H5L_CRT_TARGET_ID_NAME, H5L_CRT_TARGET_ID_SIZE, &target_id, + 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, H5L_CRT_TARGET_NAME_NAME, H5L_CRT_TARGET_NAME_SIZE, &target_name, + 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, H5L_CRT_LINK_TYPE_NAME, H5L_CRT_LINK_TYPE_SIZE, &link_type, + 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, H5L_CRT_UDATA_NAME, H5L_CRT_UDATA_SIZE, &udata, + 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, H5L_CRT_UDATA_SIZE_NAME, H5L_CRT_UDATA_SIZE_SIZE, &udata_size, + 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 ab3f1d0..bd7e690 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 */ @@ -42,7 +44,6 @@ typedef struct H5P_genplist_t H5P_genplist_t; typedef struct H5P_genclass_t H5P_genclass_t; - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -74,6 +75,7 @@ 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); 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 654772a..6cba897 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -291,6 +291,11 @@ 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 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); @@ -29,6 +29,7 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Rpkg.h" /* References */ #include "H5Sprivate.h" /* Dataspaces */ +#include "H5VLprivate.h" /* VOL plugins */ /* Local macro definitions */ @@ -523,29 +524,28 @@ 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 *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ 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 token for the Object location through the VOL */ + if(H5VL_object_lookup (obj_id, H5VL_OBJECT_LOOKUP_BY_REF, &location, ref_type, _ref) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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 dereference object") + /* Open the object through the VOL */ + if((ret_value = H5VL_object_open_by_loc(obj_id, location, oapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index d0c79a8..bf75a0a 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -47,6 +47,7 @@ #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 /****************/ @@ -184,27 +185,26 @@ 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 *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ 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; + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup (obj_id, H5VL_OBJECT_LOOKUP_BY_REF, &location, ref_type, _ref) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") - /* 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") + /* Open the object through the VOL */ + if((ret_value = H5VL_object_open_by_loc(obj_id, location, H5P_DATASET_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 91aed1e..b1d1058 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -1240,7 +1240,7 @@ H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t /* Check args */ HDassert(buf); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(H5I_DATATYPE == H5I_get_type(type_id) || H5I_DATATYPE_PUBLIC == H5I_get_type(type_id)); HDassert(space); HDassert(op); @@ -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 @@ -1635,12 +1636,22 @@ H5Tcopy(hid_t type_id) { H5T_t *dt; /* Pointer to the datatype to copy */ H5T_t *new_dt = NULL; + H5I_type_t id_type; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", type_id); - switch(H5I_get_type(type_id)) { + id_type = H5I_get_type(type_id); + if (H5I_DATATYPE_PUBLIC == id_type || H5I_DATASET_PUBLIC == id_type) { + H5VL_id_wrapper_t *id_wrapper; + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(type_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + type_id = id_wrapper->obj_id; + id_type = H5I_get_type(type_id); + } + + switch(id_type) { case H5I_DATATYPE: /* The argument is a datatype handle */ if(NULL == (dt = (H5T_t *)H5I_object(type_id))) @@ -1717,16 +1728,22 @@ H5Tclose(hid_t type_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", 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") - if(H5T_STATE_IMMUTABLE == dt->shared->state) - 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") - + /* if this is a named datatype, go through the VOL layer */ + if (H5I_DATATYPE_PUBLIC == H5I_get_type(type_id)) { + if(H5VL_object_close(type_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to free datatype") + } + else { + /* Check args */ + if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_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") + + /* 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") + } done: FUNC_LEAVE_API(ret_value) } /* end H5Tclose() */ diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index a49d66e..7e90a2d 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -39,7 +39,7 @@ #include "H5Lprivate.h" /* Links */ #include "H5Pprivate.h" /* Property lists */ #include "H5Tpkg.h" /* Datatypes */ - +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -120,22 +120,16 @@ 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 */ 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(!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,10 +152,9 @@ 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") - + /* Open the object through the VOL */ + if((ret_value = H5VL_datatype_commit(loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") done: FUNC_LEAVE_API(ret_value) } /* end H5Tcommit2() */ @@ -551,23 +544,13 @@ 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 */ 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 +560,11 @@ 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; - - /* 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(NULL == (type = H5T_open(&type_loc, dxpl_id))) - 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") + /* Open the datatype through the VOL */ + if((ret_value = H5VL_datatype_open(loc_id, name, tapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open datatype") 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 */ - FUNC_LEAVE_API(ret_value) } /* end H5Topen2() */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 6795ef1..516ac92 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -629,7 +629,8 @@ 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 +677,8 @@ 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 +1052,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 +1095,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 +1460,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 +1497,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 +1565,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 +1582,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 +2110,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 +2132,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 +2360,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 +2419,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 +2741,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 +2768,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") @@ -2970,7 +2972,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") @@ -2995,7 +2997,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 */ @@ -3278,7 +3280,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); @@ -3303,7 +3305,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") /* @@ -3436,7 +3438,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") @@ -3452,7 +3455,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") /* @@ -3858,7 +3862,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; @@ -3878,7 +3883,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; @@ -4403,7 +4409,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") @@ -4427,7 +4433,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") /* @@ -8697,7 +8703,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; @@ -8715,7 +8722,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; @@ -9286,7 +9294,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; @@ -9304,7 +9313,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/H5Tvlen.c b/src/H5Tvlen.c index 267692c..ace0a73 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -1164,7 +1164,7 @@ H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned UNUSED ndim, const hsize_t HDassert(elem); HDassert(vl_alloc_info); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(H5I_DATATYPE == H5I_get_type(type_id) || H5I_DATATYPE_PUBLIC == H5I_get_type(type_id)); /* Check args */ if(NULL == (dt = H5I_object_verify(type_id, H5I_DATATYPE))) diff --git a/src/H5VL.c b/src/H5VL.c new file mode 100644 index 0000000..f821463 --- /dev/null +++ b/src/H5VL.c @@ -0,0 +1,2274 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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_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 */ + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5VL_free_cls(H5VL_class_t *cls); +static herr_t H5VL_free_id_wrapper(H5VL_id_wrapper_t *id_struct); + + +/*------------------------------------------------------------------------- + * 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, (size_t)H5I_VOL_HASHSIZE, 0, (H5I_free_t)H5VL_free_cls)<H5I_FILE) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize interface") + + /* Register high level file user id */ + if(H5I_register_type(H5I_FILE_PUBLIC, (size_t)H5I_FILE_PUBLIC_HASHSIZE, 0, (H5I_free_t)H5VL_free_id_wrapper)<H5I_FILE) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize interface") + /* Register high level group user id */ + if(H5I_register_type(H5I_GROUP_PUBLIC, (size_t)H5I_GROUP_PUBLIC_HASHSIZE, 0, (H5I_free_t)H5VL_free_id_wrapper)<H5I_FILE) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize interface") + /* Register high level dataset user id */ + if(H5I_register_type(H5I_DATASET_PUBLIC, (size_t)H5I_DATASET_PUBLIC_HASHSIZE, 0, (H5I_free_t)H5VL_free_id_wrapper)<H5I_FILE) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize interface") + /* Register high level attribute user id */ + if(H5I_register_type(H5I_ATTR_PUBLIC, (size_t)H5I_ATTR_PUBLIC_HASHSIZE, 0, (H5I_free_t)H5VL_free_id_wrapper)<H5I_FILE) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize interface") + /* Register high level datatype user id */ + if(H5I_register_type(H5I_DATATYPE_PUBLIC, (size_t)H5I_DATATYPE_PUBLIC_HASHSIZE, 0, (H5I_free_t)H5VL_free_id_wrapper)<H5I_FILE) + HGOTO_ERROR(H5E_ATOM, 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, n2 = 0, n3 = 0, n4 = 0, n5 = 0, n6 = 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((n2=H5I_nmembers(H5I_FILE_PUBLIC))!=0) { + H5I_clear_type(H5I_FILE_PUBLIC, TRUE, FALSE); + term = FALSE; + } else { + H5I_dec_type_ref(H5I_FILE_PUBLIC); + } + + if((n3=H5I_nmembers(H5I_DATASET_PUBLIC))!=0) { + H5I_clear_type(H5I_DATASET_PUBLIC, FALSE, FALSE); + term = FALSE; + } else { + H5I_dec_type_ref(H5I_DATASET_PUBLIC); + } + + if((n4=H5I_nmembers(H5I_DATATYPE_PUBLIC))!=0) { + H5I_clear_type(H5I_DATATYPE_PUBLIC, FALSE, FALSE); + term = FALSE; + } else { + H5I_dec_type_ref(H5I_DATATYPE_PUBLIC); + } + + if((n5=H5I_nmembers(H5I_GROUP_PUBLIC))!=0) { + H5I_clear_type(H5I_GROUP_PUBLIC, FALSE, FALSE); + term = FALSE; + } else { + H5I_dec_type_ref(H5I_GROUP_PUBLIC); + } + + if((n6=H5I_nmembers(H5I_ATTR_PUBLIC))!=0) { + H5I_clear_type(H5I_ATTR_PUBLIC, FALSE, FALSE); + term = FALSE; + } else { + H5I_dec_type_ref(H5I_ATTR_PUBLIC); + } + + if (term) { + H5_interface_initialize_g = 0; + n = 1; + } + else { + n = n1 + n2 + n3 + n4 + n5 + n6; + } + } + + 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_xfree(cls); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_free_cls() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_free_id_wrapper + * + * Purpose: Frees the structure of a user level ID + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_free_id_wrapper(H5VL_id_wrapper_t *id_struct) +{ + int ref_count; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(id_struct); + + /* If we are freeing the id wrapper, then we need to call the free + callback on the object ID in this wrapper, so just keep + decrementing the ref count on the object id till it gets to 0 + and calls its free function */ + ref_count = H5I_get_ref(id_struct->obj_id, TRUE); + while (ref_count > 0) { + if((ref_count = H5I_dec_app_ref(id_struct->obj_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free") + } + + /* decrement the number of reference on the VOL plugin */ + id_struct->vol_plugin->nrefs --; + + /* free the ID wrapper */ + H5MM_xfree(id_struct); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_free_id_wrapper() */ + + +/*------------------------------------------------------------------------- + * 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: 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); + /*MSC - check required funciton pointers */ + + /* 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: 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: 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 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_fapl_open(H5P_genplist_t *plist, H5VL_class_t *vol_cls) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Increment the reference count on vol and copy vol info */ + vol_cls->nrefs++; + + /* 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") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_fapl_open() */ + + +/*------------------------------------------------------------------------- + * 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) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL != vol_cls) { + vol_cls->nrefs--; + //H5MM_xfree(vol_cls); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_fapl_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_open + * + * Purpose: Opens a file through the VOL. + * + * Return: Success: User ID of the new file. This ID is of type + * H5I_FILE_PUBLIC which contains the VOL id and the actual file ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_file_open(const char *name, unsigned flags, hid_t fapl_id) +{ + H5VL_class_t *vol_plugin; /* VOL for file */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + H5P_genplist_t *plist; /* Property list pointer */ + hid_t file_id; + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* 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_plugin) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol plugin") + + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if((file_id = (vol_plugin->file_cls.open)(name, flags, fapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "open failed") + + /* Create a new id that points to a struct that holds the file id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper->obj_id = file_id; + id_wrapper->vol_plugin = vol_plugin; + vol_plugin->nrefs ++; + + if((ret_value = H5I_register(H5I_FILE_PUBLIC, id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_create + * + * Purpose: Creates a file through the VOL + * + * Return: Success: User ID of the new file. This ID is of type + * H5I_FILE_PUBLIC which contains the VOL id and the actual file ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +{ + H5VL_class_t *vol_plugin; /* VOL for file */ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + H5P_genplist_t *plist; /* Property list pointer */ + hid_t file_id; + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* 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_plugin) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol plugin ID") + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_plugin->file_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file create' method") + /* call the corresponding VOL create callback */ + if((file_id = (vol_plugin->file_cls.create)(name, flags, fcpl_id, fapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "create failed") + + /* Create a new id that points to a struct that holds the file id and the VOL id */ + /* Allocate new id structure */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper->obj_id = file_id; + id_wrapper->vol_plugin = vol_plugin; + vol_plugin->nrefs ++; + + if((ret_value = H5I_register(H5I_FILE_PUBLIC, id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_create() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_FILE_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->file_cls.close) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file close' method") + if((ret_value = (id_wrapper->vol_plugin->file_cls.close)(id_wrapper->obj_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "close failed") + + id_wrapper->vol_plugin->nrefs--; + if(H5I_dec_app_ref(uid) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to decrement ref count on user ID") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_close() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid, H5F_scope_t scope) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_FILE_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->file_cls.flush) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file flush' method") + if((ret_value = (id_wrapper->vol_plugin->file_cls.flush)(id_wrapper->obj_id, scope)) < 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(hid_t uid, H5VL_file_get_t get_type, ...) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + va_list arguments; /* argument list passed from the API call */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(uid); + /* Check/fix arguments. */ + if (H5I_FILE_PUBLIC != id_type && H5I_GROUP_PUBLIC != id_type && + H5I_DATATYPE_PUBLIC != id_type && H5I_DATASET_PUBLIC != id_type && + H5I_ATTR_PUBLIC != id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->file_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file get' method") + + va_start(arguments, get_type); + if((ret_value = (id_wrapper->vol_plugin->file_cls.get)(id_wrapper->obj_id, get_type, 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_group_create + * + * Purpose: Creates a group through the VOL + * + * Return: Success: User ID of the new group. This ID is of type + * H5I_GROUP_PUBLIC which contains the VOL plugin and the actual group ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_group_create(hid_t uid, const char *name, hid_t gcpl_id, hid_t gapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the group will be created */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new created group*/ + hid_t group_id; /* actual group ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the corresponding VOL create callback exists */ + if(NULL == id_wrapper1->vol_plugin->group_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `group create' method") + + /* call the corresponding VOL create callback */ + if((group_id = (id_wrapper1->vol_plugin->group_cls.create) + (id_wrapper1->obj_id, name, gcpl_id, gapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "create failed") + + /* Create a new id that points to a struct that holds the group id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = group_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + if((ret_value = H5I_register(H5I_GROUP_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_group_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_group_open + * + * Purpose: Opens a group through the VOL + * + * Return: Success: User ID of the new group. This ID is of type + * H5I_GROUP_PUBLIC which contains the VOL plugin and the actual group ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_group_open(hid_t loc_id, const char *name, hid_t gapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the group will be opend */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new opend group*/ + hid_t group_id; /* actual group ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == id_wrapper1->vol_plugin->group_cls.open) { + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ + + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, name, gapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") + + /* Open the object through the VOL */ + if((ret_value = H5VL_object_open_by_loc(loc_id, location, gapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") + } + else { + /* call the corresponding VOL open callback */ + if((group_id = (id_wrapper1->vol_plugin->group_cls.open) + (id_wrapper1->obj_id, name, gapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "open failed") + + /* Create a new id that points to a struct that holds the group id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = group_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + if((ret_value = H5I_register(H5I_GROUP_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_group_open() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_GROUP_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* if the VOL class does not implement a specific group close + callback, try the generic object close */ + if(NULL == id_wrapper->vol_plugin->group_cls.close) { + if(H5VL_object_close(uid) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") + } + else { + if((ret_value = (id_wrapper->vol_plugin->group_cls.close)(id_wrapper->obj_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + + id_wrapper->vol_plugin->nrefs--; + + if(H5I_dec_app_ref(uid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on user ID") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_group_close() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid, H5VL_group_get_t get_type, ...) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + va_list arguments; /* argument list passed from the API call */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(uid); + /* Check/fix arguments. */ + if(H5I_GROUP_PUBLIC != id_type && H5I_FILE_PUBLIC != id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->group_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `group get' method") + + va_start (arguments, get_type); + if((ret_value = (id_wrapper->vol_plugin->group_cls.get) + (id_wrapper->obj_id, get_type, 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_object_open_by_loc + * + * Purpose: Opens a object through the VOL + * + * Return: Success: User ID of the new object. This ID is of type + * H5I_OBJECT_PUBLIC which contains the VOL plugin and the actual object ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_object_open_by_loc(hid_t uid, void *obj_loc, hid_t lapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the object will be opend */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new opend object*/ + H5I_type_t id_type; + hid_t object_id; /* actual object ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the corresponding VOL open callback exists */ + if(NULL == id_wrapper1->vol_plugin->object_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object open' method") + + /* call the corresponding VOL open callback */ + if((object_id = (id_wrapper1->vol_plugin->object_cls.open) + (id_wrapper1->obj_id, obj_loc, lapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "open failed") + + /* Create a new id that points to a struct that holds the object id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = object_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + id_type = H5I_get_type(object_id); + + if (H5I_GROUP == id_type) { + if((ret_value = H5I_register(H5I_GROUP_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize object handle") + } + else if (H5I_DATATYPE == id_type) { + if((ret_value = H5I_register(H5I_DATATYPE_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize object handle") + } + else if (H5I_DATASET == id_type) { + if((ret_value = H5I_register(H5I_DATASET_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize object handle") + } + else { + ret_value = object_id; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_open_by_loc() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + H5I_type_t id_type; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(uid); + + /* In case of a named datatype being closed with H5Oopen after an + H5Tcommit, the id is still of type H5I_DATATYPE and not + H5I_DATATYPE_PUBLIC. In that case we just fall back to the + native implementation */ + if(H5I_DATATYPE == id_type) { + if(H5I_object(uid) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object") + if(H5I_dec_app_ref(uid) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object") + HGOTO_DONE(ret_value) + } + + /* Check id */ + if(H5I_GROUP_PUBLIC != H5I_get_type(uid) && H5I_DATASET_PUBLIC != H5I_get_type(uid) && + H5I_DATATYPE_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->object_cls.close) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object close' method") + if((ret_value = (id_wrapper->vol_plugin->object_cls.close)(id_wrapper->obj_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + + id_wrapper->vol_plugin->nrefs--; + if(H5I_dec_app_ref(uid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on user ID") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_close() */ + + +/*------------------------------------------------------------------------- + * 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 uid, H5VL_object_lookup_t lookup_type, ...) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + va_list arguments; /* argument list passed from the API call */ + H5I_type_t id_type; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(uid); + /* Check id */ + if(H5I_FILE_PUBLIC != id_type && H5I_GROUP_PUBLIC != id_type && + H5I_DATASET_PUBLIC != id_type && H5I_DATATYPE_PUBLIC != id_type && + H5I_ATTR_PUBLIC != id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* lookup the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->object_cls.lookup) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object lookup' method") + + va_start (arguments, lookup_type); + if((ret_value = (id_wrapper->vol_plugin->object_cls.lookup)(id_wrapper->obj_id, lookup_type, + 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_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(hid_t uid, H5VL_object_get_t get_type, ...) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + va_list arguments; /* argument list passed from the API call */ + H5I_type_t id_type; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(uid); + /* Check id */ + if(H5I_GROUP_PUBLIC != id_type && H5I_DATASET_PUBLIC != id_type && + H5I_DATATYPE_PUBLIC != id_type && H5I_FILE_PUBLIC != id_type && + H5I_ATTR_PUBLIC != id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->object_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object get' method") + + va_start (arguments, get_type); + if((ret_value = (id_wrapper->vol_plugin->object_cls.get)(id_wrapper->obj_id, get_type, + 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_datatype_commit + * + * Purpose: Commits a datatype to the file through the VOL + * + * Return: Success: Positive + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_datatype_commit(hid_t uid, const char *name, hid_t type_id, hid_t lcpl_id, + hid_t tcpl_id, hid_t tapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* wrapper object of the location where the datatype will be commitd */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the corresponding VOL commit callback exists */ + if(NULL == id_wrapper1->vol_plugin->datatype_cls.commit) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `datatype commit' method") + + /* call the corresponding VOL commit callback */ + if((ret_value = (id_wrapper1->vol_plugin->datatype_cls.commit) + (id_wrapper1->obj_id, name, type_id, lcpl_id, tcpl_id, tapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "commit failed") + +#if 0 + /* Create a new id that points to a struct that holds the datatype id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + if((id_wrapper2->obj_id = H5I_register(H5I_DATATYPE, H5I_object(type_id), TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize datatype handle") + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + H5I_subst(type_id, id_wrapper2); + //H5I_remove_verify(type_id, H5I_DATATYPE); + +#endif + +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. This ID is of type + * H5I_DATATYPE_PUBLIC which contains the VOL plugin and the actual datatype ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_datatype_open(hid_t loc_id, const char *name, hid_t tapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the datatype will be opend */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new opend datatype*/ + hid_t datatype_id; /* actual datatype ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == id_wrapper1->vol_plugin->datatype_cls.open) { + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ + + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, name, tapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") + + /* Open the object through the VOL */ + if((ret_value = H5VL_object_open_by_loc(loc_id, location, tapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") + } + else { + /* call the corresponding VOL open callback */ + if((datatype_id = (id_wrapper1->vol_plugin->datatype_cls.open) + (id_wrapper1->obj_id, name, tapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "open failed") + + /* Create a new id that points to a struct that holds the datatype id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = datatype_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + if((ret_value = H5I_register(H5I_DATATYPE_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize datatype handle") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_datatype_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_create + * + * Purpose: Creates a dataset through the VOL + * + * Return: Success: User ID of the new dataset. This ID is of type + * H5I_DATASET_PUBLIC which contains the VOL plugin and the actual dataset ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_dataset_create(hid_t uid, const char *name, hid_t dcpl_id, hid_t dapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the dataset will be created */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new created dataset*/ + hid_t dataset_id; /* actual dataset ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* unwrap the datatype id if it is a named datatype */ + { + H5VL_id_wrapper_t *id_wrapper; + hid_t type_id; + H5P_genplist_t *plist; + /* 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") + + /* get creation properties */ + if(H5P_get(plist, H5D_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for datatype id") + + if(H5I_DATATYPE_PUBLIC == H5I_get_type(type_id)) { + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(type_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(H5P_set(plist, H5D_CRT_TYPE_ID_NAME, &(id_wrapper->obj_id)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + } + } + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the corresponding VOL create callback exists */ + if(NULL == id_wrapper1->vol_plugin->dataset_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset create' method") + + /* call the corresponding VOL create callback */ + if((dataset_id = (id_wrapper1->vol_plugin->dataset_cls.create) + (id_wrapper1->obj_id, name, dcpl_id, dapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "create failed") + + /* Create a new id that points to a struct that holds the dataset id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = dataset_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + if((ret_value = H5I_register(H5I_DATASET_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_open + * + * Purpose: Opens a dataset through the VOL + * + * Return: Success: User ID of the new dataset. This ID is of type + * H5I_DATASET_PUBLIC which contains the VOL plugin and the actual dataset ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_dataset_open(hid_t loc_id, const char *name, hid_t dapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the dataset will be opend */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new opend dataset*/ + hid_t dataset_id; /* actual dataset ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == id_wrapper1->vol_plugin->dataset_cls.open) { + void *location = NULL; /* a pointer to VOL specific token that indicates + the location of the object */ + + /* Get the token for the Object location through the VOL */ + if(H5VL_object_lookup (loc_id, H5VL_OBJECT_LOOKUP_BY_NAME, &location, name, dapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate object") + + /* Open the object through the VOL */ + if((ret_value = H5VL_object_open_by_loc(loc_id, location, dapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") + } + else { + /* call the corresponding VOL open callback */ + if((dataset_id = (id_wrapper1->vol_plugin->dataset_cls.open) + (id_wrapper1->obj_id, name, dapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "open failed") + + /* Create a new id that points to a struct that holds the dataset id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = dataset_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + if((ret_value = H5I_register(H5I_DATASET_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_open() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_DATASET_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* if the VOL class does not implement a specific dataset close + callback, try the generic object close */ + if(NULL == id_wrapper->vol_plugin->dataset_cls.close){ + if(H5VL_object_close(uid) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") + } + else { + if((ret_value = (id_wrapper->vol_plugin->dataset_cls.close)(id_wrapper->obj_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + + id_wrapper->vol_plugin->nrefs--; + if(H5I_dec_app_ref(uid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on user ID") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_close() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, void *buf) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_DATASET_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->dataset_cls.read) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset read' method") + if((ret_value = (id_wrapper->vol_plugin->dataset_cls.read) + (id_wrapper->obj_id, mem_type_id, mem_space_id, file_space_id, plist_id, buf)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, 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(hid_t uid, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, const void *buf) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_DATASET_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->dataset_cls.write) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset write' method") + if((ret_value = (id_wrapper->vol_plugin->dataset_cls.write) + (id_wrapper->obj_id, mem_type_id, mem_space_id, file_space_id, plist_id, buf)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, 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(hid_t uid, const hsize_t size[]) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_DATASET_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->dataset_cls.set_extent) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset set_extent' method") + if((ret_value = (id_wrapper->vol_plugin->dataset_cls.set_extent)(id_wrapper->obj_id, size)) < 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(hid_t uid, H5VL_dataset_get_t get_type, ...) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check id */ + if(H5I_DATASET_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->dataset_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset get' method") + + va_start (arguments, get_type); + if((ret_value = (id_wrapper->vol_plugin->dataset_cls.get)(id_wrapper->obj_id, get_type, + arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end (arguments); + + /* if the get_type is a named datatype, create a wrapper for it */ + if(H5VL_DATASET_GET_TYPE == get_type) { + H5VL_id_wrapper_t *temp_id_wrapper; /* user id structure */ + hid_t *ret_id; + + va_start (arguments, get_type); + ret_id = va_arg (arguments, hid_t *); + + if(H5T_committed((H5T_t *)H5I_object_verify(*ret_id, H5I_DATATYPE))) { + /* Create a new id that points to a struct that holds the attr id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (temp_id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + temp_id_wrapper->obj_id = *ret_id; + temp_id_wrapper->vol_plugin = id_wrapper->vol_plugin; + + if((*ret_id = H5I_register(H5I_DATATYPE_PUBLIC, temp_id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize attr handle") + } + va_end (arguments); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_get() */ + + +/*------------------------------------------------------------------------- + * 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, hid_t loc_id, const char *new_name, + hid_t lcpl_id, hid_t lapl_id) +{ + H5VL_class_t *vol_plugin = NULL; /* VOL plugin */ + hid_t new_id; /* unwrapped IDs */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* unwrap the target high level ID if the creation call is H5Lcreate_hard */ + if(H5VL_CREATE_HARD_LINK == create_type) { + H5P_genplist_t *plist; /* Property list pointer */ + hid_t cur_id; + + /* 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(H5P_get(plist, H5L_CRT_TARGET_ID_NAME, &cur_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current location id") + + /* Only one of the IDs can be H5L_SAME_LOC, and the other one must + be of the wrapper type. Get the VOL plugin struct in case the + link id is H5L_SAME_LOC*/ + if (H5L_SAME_LOC != cur_id && H5I_DATATYPE != H5I_get_type(cur_id)) { + H5VL_id_wrapper_t *id_wrapper; + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(cur_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + vol_plugin = id_wrapper->vol_plugin; + if(H5P_set(plist, H5L_CRT_TARGET_ID_NAME, &(id_wrapper->obj_id)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current location id") + } + } + + /* unwrap the higher level user ids. */ + if(H5L_SAME_LOC != loc_id && H5I_DATATYPE != H5I_get_type(loc_id)) { + H5VL_id_wrapper_t *id_wrapper; + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* set the vol plugin sturcture if it hasn't been done yet */ + if (NULL == vol_plugin) + vol_plugin = id_wrapper->vol_plugin; + + new_id = id_wrapper->obj_id; + } + else { + new_id = loc_id; + } + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_plugin->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->link_cls.create) + (create_type, new_id, new_name, lcpl_id, lapl_id)) < 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(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id) +{ + H5VL_class_t *vol_plugin = NULL; /* VOL plugin */ + H5VL_id_wrapper_t *id_wrapper; + hid_t new_src_id, new_dst_id; /* unwrapped IDs */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* unwrap the higher level user ids. */ + if(H5L_SAME_LOC != src_loc_id) { + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + vol_plugin = id_wrapper->vol_plugin; + new_src_id = id_wrapper->obj_id; + } + else { + new_src_id = src_loc_id; + } + + if(H5L_SAME_LOC != dst_loc_id) { + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + if(NULL == vol_plugin) + vol_plugin = id_wrapper->vol_plugin; + new_dst_id = id_wrapper->obj_id; + } + else { + new_dst_id = dst_loc_id; + } + + /* check if the corresponding VOL move callback exists */ + if(NULL == vol_plugin->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->link_cls.move) + (new_src_id, src_name, new_dst_id, dst_name, copy_flag, lcpl_id, lapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link move failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_link_move() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_link_delete + * + * Purpose: Copy or delete 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_delete(hid_t loc_id, const char *name, hid_t lapl_id) +{ + H5VL_id_wrapper_t *id_wrapper; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the corresponding VOL delete callback exists */ + if(NULL == id_wrapper->vol_plugin->link_cls.delete) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link delete' method") + + /* call the corresponding VOL delete callback */ + if((ret_value = (id_wrapper->vol_plugin->link_cls.delete) + (id_wrapper->obj_id, name, lapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link delete failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_link_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_create + * + * Purpose: Creates an attribute through the VOL + * + * Return: Success: User ID of the new attr. This ID is of type + * H5I_ATTR_PUBLIC which contains the VOL plugin and the actual attr ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_attr_create(hid_t uid, const char *name, hid_t acpl_id, hid_t aapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the attr will be created */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new created attr*/ + H5I_type_t id_type; + hid_t loc_id; /* actual attr ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(uid); + /* Check id */ + if(H5I_FILE_PUBLIC != id_type && H5I_GROUP_PUBLIC != id_type && + H5I_DATASET_PUBLIC != id_type && H5I_DATATYPE_PUBLIC != id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the corresponding VOL create callback exists */ + if(NULL == id_wrapper1->vol_plugin->attr_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr create' method") + + /* call the corresponding VOL create callback */ + if((loc_id = (id_wrapper1->vol_plugin->attr_cls.create) + (id_wrapper1->obj_id, name, acpl_id, aapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "create failed") + + /* Create a new id that points to a struct that holds the attr id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = loc_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + if((ret_value = H5I_register(H5I_ATTR_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize attr handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_open + * + * Purpose: Opens an attribute through the VOL + * + * Return: Success: User ID of the new attr. This ID is of type + * H5I_ATTR_PUBLIC which contains the VOL plugin and the actual attr ID + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_attr_open(hid_t loc_id, void *location, const char *name, hid_t aapl_id) +{ + H5VL_id_wrapper_t *id_wrapper1; /* user id structure of the location where the attr will be opend */ + H5VL_id_wrapper_t *id_wrapper2; /* user id structure of new opend attr*/ + H5I_type_t id_type; + hid_t attr_id; /* actual attr ID */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(loc_id); + /* Check id */ + if(H5I_FILE_PUBLIC != id_type && H5I_GROUP_PUBLIC != id_type && + H5I_DATASET_PUBLIC != id_type && H5I_DATATYPE_PUBLIC != id_type && + H5I_ATTR_PUBLIC != id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper1 = (H5VL_id_wrapper_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == id_wrapper1->vol_plugin->attr_cls.open) { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr open' method") + } + + /* call the corresponding VOL open callback */ + if((attr_id = (id_wrapper1->vol_plugin->attr_cls.open) + (id_wrapper1->obj_id, location, name, aapl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "open failed") + + /* Create a new id that points to a struct that holds the attr id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (id_wrapper2 = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + id_wrapper2->obj_id = attr_id; + id_wrapper2->vol_plugin = id_wrapper1->vol_plugin; + + if((ret_value = H5I_register(H5I_ATTR_PUBLIC, id_wrapper2, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize attr handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_open() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_ATTR_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + /* if the VOL class does not implement a specific attr close + callback, try the generic object close */ + if(NULL == id_wrapper->vol_plugin->attr_cls.close){ + if(H5VL_object_close(uid) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") + } + else { + if((ret_value = (id_wrapper->vol_plugin->attr_cls.close)(id_wrapper->obj_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + + id_wrapper->vol_plugin->nrefs--; + if(H5I_dec_app_ref(uid) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on user ID") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_close() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t uid, hid_t mem_type_id, void *buf) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_ATTR_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->attr_cls.read) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr read' method") + if((ret_value = (id_wrapper->vol_plugin->attr_cls.read) + (id_wrapper->obj_id, mem_type_id, buf)) < 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(hid_t uid, hid_t mem_type_id, const void *buf) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check/fix arguments. */ + if(H5I_ATTR_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->attr_cls.write) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr write' method") + if((ret_value = (id_wrapper->vol_plugin->attr_cls.write) + (id_wrapper->obj_id, mem_type_id, buf)) < 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(hid_t uid, H5VL_attr_get_t get_type, ...) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check id */ + if(H5I_ATTR_PUBLIC != H5I_get_type(uid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->attr_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr get' method") + + va_start (arguments, get_type); + if((ret_value = (id_wrapper->vol_plugin->attr_cls.get)(id_wrapper->obj_id, get_type, + arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end (arguments); + + /* if the get_type is a named datatype, create a wrapper for it */ + if(H5VL_ATTR_GET_TYPE == get_type) { + H5VL_id_wrapper_t *temp_id_wrapper; /* user id structure */ + hid_t *ret_id; + + va_start (arguments, get_type); + ret_id = va_arg (arguments, hid_t *); + + if(H5T_committed((H5T_t *)H5I_object_verify(*ret_id, H5I_DATATYPE))) { + /* Create a new id that points to a struct that holds the attr id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (temp_id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + temp_id_wrapper->obj_id = *ret_id; + temp_id_wrapper->vol_plugin = id_wrapper->vol_plugin; + + if((*ret_id = H5I_register(H5I_DATATYPE_PUBLIC, temp_id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize attr handle") + } + va_end (arguments); + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_generic + * + * Purpose: perform a plugin specific operation + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_attr_generic(hid_t uid, H5VL_attr_generic_t generic_type, ...) +{ + H5VL_id_wrapper_t *id_wrapper; /* user id structure */ + va_list arguments; /* argument list passed from the API call */ + H5I_type_t id_type; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + id_type = H5I_get_type(uid); + /* Check id */ + if(H5I_FILE_PUBLIC != id_type && H5I_GROUP_PUBLIC != id_type && + H5I_DATASET_PUBLIC != id_type && H5I_DATATYPE_PUBLIC != id_type && + H5I_ATTR_PUBLIC != id_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a user ID") + + /* get the ID struct */ + if(NULL == (id_wrapper = (H5VL_id_wrapper_t *)H5I_object(uid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid user identifier") + + if(NULL == id_wrapper->vol_plugin->attr_cls.generic) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr generic' method") + + va_start (arguments, generic_type); + if((ret_value = (id_wrapper->vol_plugin->attr_cls.generic)(id_wrapper->obj_id, generic_type, + arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "generic failed") + va_end (arguments); + + if(H5VL_ATTR_OPEN_BY_IDX == generic_type) { + H5VL_id_wrapper_t *temp_id_wrapper; /* user id structure */ + hid_t *ret_id; + + va_start (arguments, generic_type); + ret_id = va_arg (arguments, hid_t *); + + /* Create a new id that points to a struct that holds the attr id and the VOL plugin */ + /* Allocate new id structure */ + if(NULL == (temp_id_wrapper = (H5VL_id_wrapper_t *)H5MM_malloc(sizeof(H5VL_id_wrapper_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + temp_id_wrapper->obj_id = *ret_id; + temp_id_wrapper->vol_plugin = id_wrapper->vol_plugin; + + if((*ret_id = H5I_register(H5I_ATTR_PUBLIC, temp_id_wrapper, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize attr handle") + va_end (arguments); + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_generic() */ diff --git a/src/H5VLdummy.c b/src/H5VLdummy.c new file mode 100644 index 0000000..8f4131a --- /dev/null +++ b/src/H5VLdummy.c @@ -0,0 +1,294 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 dummy VOL plugin where access is to a single HDF5 file + * using HDF5 VFDs. + */ + +#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 H5O_PACKAGE /*suppress error about including H5Opkg */ +#define H5T_PACKAGE /*suppress error about including H5Tpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5VL_dummy_init_interface + + +#include "H5private.h" /* Generic Functions */ +#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 "H5FLprivate.h" /* Free lists */ +#include "H5Gpkg.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Opkg.h" /* Object headers */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5Tpkg.h" /* Datatypes */ +#include "H5VLprivate.h" /* VOL plugins */ +#include "H5VLdummy.h" /* Dummy VOL plugin */ + +/* The driver identification number, initialized at runtime */ +static hid_t H5VL_DUMMY_g = 0; + +/* Prototypes */ +static herr_t H5VL_dummy_term(void); +static hid_t H5VL_dummy_file_open(const char *name, unsigned flags, hid_t fapl_id); +static herr_t H5VL_dummy_file_close(hid_t fid); +static hid_t H5VL_dummy_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); + +H5VL_class_t H5VL_dummy_g = { + "dummy", /* name */ + 0, /* nrefs */ + H5VL_dummy_term, /*terminate */ + { /* attribute_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* delete */ + NULL /* close */ + }, + { /* datatype_cls */ + NULL, /* commit */ + NULL /* open */ + }, + { /* dataset_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, + NULL, + NULL, + NULL, + NULL + }, + { /* group_cls */ + NULL, + NULL, + NULL, + NULL + }, + { /* file_cls */ + H5VL_dummy_file_create, /* create */ + H5VL_dummy_file_open, /* open */ + NULL, + NULL, + H5VL_dummy_file_close /* close */ + }, + { /* link_cls */ + NULL, /* create */ + NULL, /* delete */ + NULL, /* move */ + NULL + }, + { /* object_cls */ + NULL, + NULL, /* move */ + NULL, /* copy */ + NULL, + NULL, + NULL + } +}; + + +/*-------------------------------------------------------------------------- +NAME + H5VL_dummy_init_interface -- Initialize interface-specific information +USAGE + herr_t H5VL_dummy_init_interface() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5VL_dummy_init currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5VL_dummy_init_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5VL_dummy_init_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dummy_init + * + * Purpose: Initialize this vol plugin by registering the driver with the + * library. + * + * Return: Success: The ID for the dummy plugin. + * Failure: Negative. + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +H5VL_class_t * +H5VL_dummy_init(void) +{ + H5VL_class_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Set return value */ + ret_value = &H5VL_dummy_g; + ret_value->nrefs ++; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dummy_init() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL_dummy_term + * + * Purpose: Shut down the VOL plugin + * + * Returns: Non-negative on success or negative on failure + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *--------------------------------------------------------------------------- + */ +static herr_t +H5VL_dummy_term(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Reset VOL ID */ + H5VL_DUMMY_g = 0; + H5VL_dummy_g.nrefs = 0; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5VL_dummy_term() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_dummy + * + * Purpose: Modify the file access property list to use the H5VL_DUMMY + * plugin defined in this source file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_dummy(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_dummy_g); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_fapl_dummy() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dummy_open + * + * Purpose: Opens a file as a dummy HDF5 file. + * + * Return: Success: A pointer to a new file data structure. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_dummy_file_open(const char *name, unsigned flags, hid_t fapl_id) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + printf ("DUMMY OPEN\n"); + + FUNC_LEAVE_NOAPI(1) +} /* end H5VL_dummy_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dummy_create + * + * Purpose: Creates a file as a dummy HDF5 file. + * + * Return: Success: A pointer to a new file data structure. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_dummy_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + printf ("DUMMY CREATE\n"); + + FUNC_LEAVE_NOAPI(2) +} /* end H5VL_dummy_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dummy_close + * + * Purpose: Closes a file. + * + * Return: Success: 0 + * Failure: -1, file not closed. + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dummy_file_close(hid_t file_id) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + printf ("DUMMY CLOSE\n"); + + FUNC_LEAVE_NOAPI(1) +} /* end H5VL_dummy_close() */ diff --git a/src/H5VLdummy.h b/src/H5VLdummy.h new file mode 100644 index 0000000..86aa0ae --- /dev/null +++ b/src/H5VLdummy.h @@ -0,0 +1,38 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 Dummy VOL plugin. + */ +#ifndef H5VLdummy_H +#define H5VLdummy_H + +#define H5VL_DUMMY (H5VL_dummy_init()) + +#ifdef __cplusplus +extern "C" { +#endif + +H5_DLL H5VL_class_t *H5VL_dummy_init(void); +H5_DLL herr_t H5Pset_fapl_dummy(hid_t fapl_id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/H5VLnative.c b/src/H5VLnative.c new file mode 100644 index 0000000..a6d21ed7 --- /dev/null +++ b/src/H5VLnative.c @@ -0,0 +1,2474 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 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 "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5Tpkg.h" /* Datatypes */ +#include "H5VLprivate.h" /* VOL plugins */ +#include "H5VLnative.h" /* Native VOL plugin */ + +/* The driver identification number, initialized at runtime */ +static hid_t H5VL_NATIVE_g = 0; + + +/* Prototypes */ +static herr_t H5VL_native_term(void); + +static hid_t H5VL_native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); +static hid_t H5VL_native_file_open(const char *name, unsigned flags, hid_t fapl_id); +static herr_t H5VL_native_file_flush(hid_t fid, H5F_scope_t scope); +static herr_t H5VL_native_file_get(hid_t file_id, H5VL_file_get_t get_type, va_list arguments); +static herr_t H5VL_native_file_close(hid_t fid); + +static hid_t H5VL_native_attr_create(hid_t loc_id, const char *attr_name, hid_t acpl_id, hid_t aapl_id); +static hid_t H5VL_native_attr_open(hid_t loc_id, void *location, const char *attr_name, hid_t aapl_id); +static herr_t H5VL_native_attr_read(hid_t attr_id, hid_t dtype_id, void *buf); +static herr_t H5VL_native_attr_write(hid_t attr_id, hid_t dtype_id, const void *buf); +static herr_t H5VL_native_attr_get(hid_t id, H5VL_attr_get_t get_type, va_list arguments); +static herr_t H5VL_native_attr_generic(hid_t id, H5VL_attr_generic_t generic_type, va_list arguments); +static herr_t H5VL_native_attr_close(hid_t attr_id); + +static hid_t H5VL_native_dataset_create(hid_t loc_id, const char *name, hid_t dcpl_id, hid_t dapl_id); +static hid_t H5VL_native_dataset_open(hid_t loc_id, const char *name, hid_t dapl_id); +static herr_t H5VL_native_dataset_read(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); +static herr_t H5VL_native_dataset_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, const void *buf); +static herr_t H5VL_native_dataset_set_extent(hid_t dset_id, const hsize_t size[]); +static herr_t H5VL_native_dataset_get(hid_t id, H5VL_dataset_get_t get_type, va_list arguments); +static herr_t H5VL_native_dataset_close(hid_t dataset_id); + +static herr_t H5VL_native_datatype_commit(hid_t loc_id, const char *name, hid_t type_id, + hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id); +static hid_t H5VL_native_datatype_open(hid_t loc_id, const char *name, hid_t tapl_id); + +static hid_t H5VL_native_group_create(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id); +static hid_t H5VL_native_group_open(hid_t loc_id, const char *name, hid_t gapl_id); +static herr_t H5VL_native_group_get(hid_t obj_id, H5VL_group_get_t get_type, va_list arguments); +static herr_t H5VL_native_group_close(hid_t group_id); + +static herr_t H5VL_native_link_create(H5VL_link_create_type_t create_type, hid_t loc_id, + const char *link_name, hid_t lcpl_id, hid_t lapl_id); +static herr_t H5VL_native_link_move(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id); +//static herr_t H5VL_native_link_delete(hid_t loc_id, char *name, H5G_traverse_t op, void *udata, hid_t lapl_id); +static herr_t H5VL_native_link_delete(hid_t loc_id, const char *name, hid_t lapl_id); + +static hid_t H5VL_native_object_open(hid_t loc_id, void *location, hid_t lapl_id); +static herr_t H5VL_native_object_get(hid_t id, H5VL_object_get_t get_type, va_list arguments); +static herr_t H5VL_native_object_lookup(hid_t loc_id, H5VL_object_lookup_t lookup_type, va_list arguments); +static herr_t H5VL_native_object_close(hid_t object_id); + +H5VL_class_t H5VL_native_g = { + "native", /* name */ + 0, /* nrefs */ + H5VL_native_term, /*terminate */ + { /* attribute_cls */ + H5VL_native_attr_create, /* create */ + H5VL_native_attr_open, /* open */ + H5VL_native_attr_read, /* read */ + H5VL_native_attr_write, /* write */ + NULL, /* delete */ + H5VL_native_attr_get, /* get */ + H5VL_native_attr_generic, /* generic */ + H5VL_native_attr_close /* close */ + }, + { /* datatype_cls */ + H5VL_native_datatype_commit, /* commit */ + H5VL_native_datatype_open /* open */ + }, + { /* 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 */ + }, + { /* group_cls */ + H5VL_native_group_create, /* create */ + H5VL_native_group_open, /* open */ + H5VL_native_group_get, /* get */ + H5VL_native_group_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_close /* close */ + }, + { /* link_cls */ + H5VL_native_link_create, /* create */ + H5VL_native_link_move, /* move */ + NULL, /* get */ + H5VL_native_link_delete /* delete */ + }, + { /* object_cls */ + H5VL_native_object_open, /* open */ + NULL, /* move */ + NULL, /* copy */ + H5VL_native_object_lookup, /* lookup */ + H5VL_native_object_get, /* get */ + 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; + ret_value->nrefs ++; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_init() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL_native_term + * + * Purpose: Shut down the VOL plugin + * + * Returns: Non-negative on success or negative on failure + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *--------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_term(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Reset VOL ID */ + H5VL_NATIVE_g = 0; + H5VL_native_g.nrefs = 0; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5VL_native_term() */ + + +/*------------------------------------------------------------------------- + * 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); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_fapl_native() */ + + +/*------------------------------------------------------------------------- + * 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 hid_t +H5VL_native_file_open(const char *name, unsigned flags, hid_t fapl_id) +{ + H5F_t *new_file; /* file struct */ + hid_t ret_value; + + 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, FAIL, "unable to open 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 handle") + + /* store a pointer to the VOL class in the file structure */ + new_file->vol_cls = &H5VL_native_g; + + /* 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_NOAPI(ret_value) +} /* end H5VL_native_file_open() */ + + +/*------------------------------------------------------------------------- + * 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 hid_t +H5VL_native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +{ + H5F_t *new_file; /* file struct */ + hid_t ret_value; + + 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, 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 handle") + + /* store a pointer to the VOL class in the file structure */ + new_file->vol_cls = &H5VL_native_g; + + /* 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_NOAPI(ret_value) +} /* end H5VL_native_file_create() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t file_id) +{ + int nref; + H5F_t *f; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check/fix arguments. */ + if(H5I_FILE != H5I_get_type(file_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + + /* get the file struct */ + if(NULL == (f = (H5F_t *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + /* 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)) { + if((nref = H5I_get_ref(f->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_ref(f->file_id) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_close() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t object_id, H5F_scope_t scope) +{ + H5F_t *f = NULL; /* File to flush */ + H5O_loc_t *oloc = NULL; /* Object location for ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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_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 */ + + 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_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(hid_t obj_id, H5VL_file_get_t get_type, va_list arguments) +{ + H5F_t *f = NULL; /* File struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check/fix arguments. */ + 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 */ + + switch (get_type) { + /* H5Fget_access_plist */ + case H5VL_FILE_GET_FAPL: + { + hid_t *plist_id = va_arg (arguments, hid_t *); + + /* 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") + break; + } + /* H5Fget_create_plist */ + case H5VL_FILE_GET_FCPL: + { + H5P_genplist_t *plist; /* Property list */ + hid_t *plist_id = va_arg (arguments, hid_t *); + + 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_filesize */ + case H5VL_FILE_GET_SIZE: + { + haddr_t eof; /* End of file address */ + hsize_t *ret = va_arg (arguments, hsize_t *); + + /* 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_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 *); + + /* 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); + + /* 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: + { + H5F_info2_t *finfo = va_arg (arguments, H5F_info2_t *); + + /* 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_intent */ + case H5VL_FILE_GET_INTENT: + { + unsigned *ret = va_arg (arguments, unsigned *); + + /* 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: + { + char *name = va_arg (arguments, char *); + ssize_t *ret = va_arg (arguments, ssize_t *); + size_t size = va_arg (arguments, size_t); + size_t len; + + 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; + } + /* H5Fget_vfd_handle */ + case H5VL_FILE_GET_VFD_HANDLE: + { + void **file_handle = va_arg (arguments, void **); + hid_t fapl = va_arg (arguments, hid_t); + + /* 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; + } + /* H5Fget_mdc_config */ + case H5VL_FILE_GET_MDC_CONF: + { + H5AC_cache_config_t *config_ptr = va_arg (arguments, H5AC_cache_config_t *); + + /* 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 *); + + /* 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; + + /* 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; + } + 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_group_create + * + * Purpose: Creates a group inside a native h5 file. + * + * Return: Success: group id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +static hid_t +H5VL_native_group_create(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id) +{ + 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; + hid_t 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, FAIL, "can't find object for ID") + + /* get creation properties */ + if(H5P_get(plist, H5G_CRT_LCPL_ID_NAME, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for lcpl id") + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + /* 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, FAIL, "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, 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") + +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, FAIL, "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, FAIL, "unable to decrement refcount on newly created object") + } /* end if */ + } + + if(ret_value < 0) + if(grp && H5G_close(grp) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") + + 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 hid_t +H5VL_native_group_open(hid_t loc_id, const char *name, hid_t gapl_id) +{ + H5G_loc_t loc; /* Location to open group */ + H5G_t *grp = NULL; /* New group opend */ + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + /* 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") + + /* 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") + +done: + if(ret_value < 0) + if(grp && H5G_close(grp) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_group_open() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t group_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(NULL == H5I_object_verify(group_id,H5I_GROUP)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + + /* + * Decrement the counter on the group atom. It will be freed if the count + * reaches zero. + */ + if(H5I_dec_app_ref(group_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_group_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_group_get + * + * Purpose: Gets certain data about a file + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_group_get(hid_t obj_id, H5VL_group_get_t get_type, 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; + H5G_t *grp = NULL; + + /* Check args */ + if(NULL == (grp = (H5G_t *)H5I_object_verify(obj_id, H5I_GROUP))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + + new_gcpl_id = va_arg (arguments, hid_t *); + + 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; + } + /* H5Fget_info2 */ + case H5VL_GROUP_GET_INFO: + { + H5G_info_t *grp_info = va_arg (arguments, H5G_info_t *); + H5G_loc_t *obj_loc = va_arg (arguments, H5G_loc_t *); + H5G_loc_t loc; + + if(H5G_loc(obj_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + if(!H5F_addr_defined(obj_loc->oloc->addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no address supplied") + + /* Retrieve the group's information */ + if(H5G__obj_info(obj_loc->oloc, grp_info, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + + if(H5G_loc_free(obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from group") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * 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 hid_t +H5VL_native_object_open(hid_t loc_id, void *location, hid_t lapl_id) +{ + H5G_loc_t loc; + H5G_loc_t *obj_loc = (H5G_loc_t *)location; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!H5F_addr_defined(obj_loc->oloc->addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no address supplied") + + /* 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") + +done: + if(ret_value < 0) + if(H5G_loc_free(obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_open() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t object_id) +{ + 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(H5I_get_type(object_id)) { + case H5I_GROUP: + case H5I_DATATYPE: + case H5I_DATASET: + if(H5I_object(object_id) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object") + if(H5I_dec_app_ref(object_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close 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_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() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t id, H5VL_object_get_t get_type, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + H5G_loc_t loc; /* Location of group */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc(id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + switch (get_type) { + /* 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 *); + H5G_loc_t *obj_loc = va_arg (arguments, H5G_loc_t *); + hbool_t loc_set = FALSE; + + if(NULL == obj_loc) { + obj_loc = &loc; + } + else { + loc_set = TRUE; + } + + /* Retrieve the object's information */ + if(H5O_get_info(obj_loc->oloc, H5AC_ind_dxpl_id, TRUE, obj_info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve object info") + + if(loc_set && H5G_loc_free(obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + break; + } + /* H5Oget_comment / H5Oget_comment_by_name */ + case H5VL_OBJECT_GET_COMMENT: + { + ssize_t *ret = va_arg (arguments, ssize_t *); + char *comment = va_arg (arguments, char *); + size_t bufsize = va_arg (arguments, size_t); + char *name = va_arg (arguments, char *); + hid_t lapl_id = va_arg (arguments, hid_t); + + /* Retrieve the object's comment */ + if((*ret = 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") + + 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_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_object_lookup_t lookup_type, va_list arguments) +{ + H5G_loc_t loc; + H5G_loc_t *obj_loc; + H5G_name_t obj_path; /* Opened object group hier. path */ + H5G_loc_t **location; + haddr_t obj_addr; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + location = va_arg (arguments, H5G_loc_t **); + *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));//*location; + obj_loc->path = (H5G_name_t *) H5MM_malloc (sizeof (H5G_name_t));//&obj_path; + H5G_loc_reset(obj_loc); + + switch (lookup_type) { + case H5VL_OBJECT_LOOKUP: + 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_LOOKUP_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_LOOKUP_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_LOOKUP_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_LOOKUP_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: + HDassert("unknown reference type" && 0); + 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 */ + + //if(H5G_name_free(obj_loc.path) < 0) + //HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free path") +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_lookup() */ + + +/*------------------------------------------------------------------------- + * 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 herr_t +H5VL_native_datatype_commit(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, + hid_t tcpl_id, hid_t tapl_id) +{ + H5G_loc_t loc; /* Location to commit datatype */ + H5T_t *type; /* Datatype for ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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") + + /* 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") + +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 hid_t +H5VL_native_datatype_open(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; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + /* 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; + + /* 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(NULL == (type = H5T_open(&type_loc, dxpl_id))) + 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") + +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 */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_datatype_open() */ + + +/*------------------------------------------------------------------------- + * 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 hid_t +H5VL_native_dataset_create(hid_t loc_id, const char *name, hid_t dcpl_id, hid_t dapl_id) +{ + 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 */ + hid_t 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, FAIL, "can't find object for ID") + + /* get creation properties */ + if(H5P_get(plist, H5D_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for datatype id") + if(H5P_get(plist, H5D_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for space id") + if(H5P_get(plist, H5D_CRT_LCPL_ID_NAME, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for lcpl 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") + + /* 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, 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") + } + /* 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, 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") + } +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, 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 */ + } + if(ret_value < 0) + if(dset && H5D_close(dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") + + 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 hid_t +H5VL_native_dataset_open(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 */ + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + /* 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, FAIL, "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, FAIL, "can't get object type") + if(obj_type != H5O_TYPE_DATASET) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset") + + /* 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") + + /* 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") + +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 */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_open() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t dset_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(NULL == H5I_object_verify(dset_id, H5I_DATASET)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + /* + * Decrement the counter on the dataset. It will be freed if the count + * reaches zero. + * + * Pass in TRUE for the 3rd parameter to tell the function to remove + * dataset's ID even though the freeing function might fail. Please + * see the comments in H5I_dec_ref for details. (SLU - 2010/9/7) + */ + if(H5I_dec_app_ref_always_close(dset_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_close() */ + + +/*------------------------------------------------------------------------- + * 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(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 */ + + FUNC_ENTER_NOAPI_NOINIT + + /* 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(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(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) +{ + 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 */ + + FUNC_ENTER_NOAPI_NOINIT + + /* 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(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; + + /* 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") + +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(hid_t dset_id, const hsize_t size[]) +{ + H5D_t *dset = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + /* 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(hid_t id, H5VL_dataset_get_t get_type, va_list arguments) +{ + H5D_t *dset = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(NULL == (dset = (H5D_t *)H5I_object_verify(id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + 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(FAIL==(ret_value=H5D_get_space_status(dset, allocation, H5AC_ind_dxpl_id))) + 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 */ + *ret = H5D_get_storage_size(dset, H5AC_ind_dxpl_id); + break; + } + /* H5Dget_offset */ + case H5VL_DATASET_GET_OFFSET: + { + haddr_t *ret = va_arg (arguments, haddr_t *); + + /* Set return value */ + *ret = H5D_get_offset(dset); + 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_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, hid_t loc_id, const char *link_name, + hid_t lcpl_id, hid_t lapl_id) +{ + + 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_CREATE_HARD_LINK: + { + H5G_loc_t cur_loc; + H5G_loc_t link_loc; + hid_t cur_loc_id; + char *cur_name = NULL; + + if(H5P_get(plist, H5L_CRT_TARGET_ID_NAME, &cur_loc_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current location id") + if(H5P_get(plist, H5L_CRT_TARGET_NAME_NAME, &cur_name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current name") + + 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(loc_id != H5L_SAME_LOC && H5G_loc(loc_id, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + /* H5Lcreate_hard */ + if (NULL != cur_name) { + 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(cur_loc_id == H5L_SAME_LOC) + cur_loc_p = link_loc_p; + else if(loc_id == H5L_SAME_LOC) + 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_name, link_loc_p, link_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, link_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_CREATE_SOFT_LINK: + { + char *target_name; + H5G_loc_t link_loc; /* Group location for new link */ + + if(H5G_loc(loc_id, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + if(H5P_get(plist, H5L_CRT_TARGET_NAME_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, link_name, + lcpl_id, lapl_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + break; + } + case H5VL_CREATE_UD_LINK: + { + H5G_loc_t link_loc; /* Group location for new link */ + H5L_type_t link_type; + void *udata; + size_t udata_size; + + if(H5G_loc(loc_id, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + if(H5P_get(plist, H5L_CRT_LINK_TYPE_NAME, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for link type") + if(H5P_get(plist, H5L_CRT_UDATA_NAME, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for udata") + if(H5P_get(plist, H5L_CRT_UDATA_SIZE_NAME, &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, 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") + 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(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id) +{ + H5G_loc_t src_loc, *src_loc_p; + H5G_loc_t dst_loc, *dst_loc_p; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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") + + /* 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/Copy the link */ + if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_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_delete + * + * 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_delete(hid_t loc_id, const char *name, hid_t lapl_id) +{ + H5G_loc_t loc; /* Object location */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + /* Unlink */ + if(H5L_delete(&loc, name, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + + /* Traverse the group hierarchy to remove the link + if(H5G_traverse(&loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, + op, (H5L_trav_rm_t *)udata, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_link_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_create + * + * Purpose: Creates an attribute on an object. + * + * Return: Success: attr id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static hid_t +H5VL_native_attr_create(hid_t loc_id, const char *attr_name, hid_t acpl_id, hid_t UNUSED aapl_id) +{ + H5G_loc_t loc; /* Object location */ + H5P_genplist_t *plist; /* Property list pointer */ + hid_t type_id, space_id; + H5T_t *type; /* Datatype to use for attribute */ + H5S_t *space; /* Dataspace to use for attribute */ + void *location = NULL; + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + /* 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") + + /* get creation properties */ + if(H5P_get(plist, H5A_CRT_TYPE_ID_NAME, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for datatype id") + if(H5P_get(plist, H5A_CRT_SPACE_ID_NAME, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for space id") + if(H5P_get(plist, H5A_CRT_LOCATION_NAME, &location) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for lcpl id") + + 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(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") + + if(NULL == location) { /* H5Acreate */ + /* 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") + } + else { /* H5Acreate_by_name */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5G_loc_t *obj_loc = (H5G_loc_t *)location; + /* Set up opened group location to fill in */ + //obj_loc.oloc = oloc;; + //obj_loc.path = &obj_path; + //H5G_name_reset(obj_loc.path); + /* 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") + + if(H5G_loc_free(obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + } + +done: + 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 hid_t +H5VL_native_attr_open(hid_t loc_id, void *location, const char *attr_name, hid_t UNUSED aapl_id) +{ + H5G_loc_t loc; /* Object location */ + H5A_t *attr = NULL; /* Attribute opened */ + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + /* 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(NULL != location) { /* H5Aopen_by_name */ + H5G_loc_t *obj_loc = (H5G_loc_t *)location; + + /* Read in attribute from object header */ + if(NULL == (attr = H5O_attr_open_by_name(obj_loc->oloc, attr_name, H5AC_ind_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header") + + if(H5G_loc_free(obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + + } + else { /* 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, FAIL, "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, FAIL, "unable to initialize 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_NOAPI(ret_value) + +} /* end H5VL_native_attr_open() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t attr_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check arguments */ + if(NULL == H5I_object_verify(attr_id, H5I_ATTR)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") + + /* Decrement references to that atom (and close it) */ + if(H5I_dec_app_ref(attr_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_close() */ + + +/*------------------------------------------------------------------------- + * 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(hid_t attr_id, hid_t dtype_id, void *buf) +{ + H5A_t *attr; /* Attribute object for ID */ + H5T_t *mem_type; /* Memory datatype */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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") + + /* 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") + +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(hid_t attr_id, hid_t dtype_id, const void *buf) +{ + H5A_t *attr; /* Attribute object for ID */ + H5T_t *mem_type; /* Memory datatype */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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") + + /* 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") + +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(hid_t attr_id, H5VL_attr_get_t get_type, va_list arguments) +{ + H5A_t *attr; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check arguments */ + if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") + + switch (get_type) { + /* H5Aget_space */ + case H5VL_ATTR_GET_SPACE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + 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 *); + + 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 *); + + 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: + { + ssize_t *ret_val = va_arg (arguments, ssize_t *); + size_t buf_size = va_arg (arguments, size_t); + char *buf = va_arg (arguments, char *); + + /* 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") + + break; + } + /* H5Aget_info */ + case H5VL_ATTR_GET_INFO: + { + H5A_info_t *ainfo = va_arg (arguments, H5A_info_t *); + + if(H5A_get_info(attr, ainfo) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get attribute info") + + break; + } + case H5VL_ATTR_GET_STORAGE_SIZE: + { + hsize_t *ret = va_arg (arguments, hsize_t *); + + /* 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_generic + * + * Purpose: Perform a plugin specific operation for an attribute + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_attr_generic(hid_t loc_id, H5VL_attr_generic_t generic_type, va_list arguments) +{ + H5A_t *attr = NULL; /* Attribute opened */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (generic_type) { + /* H5Aopen_by_idx */ + case H5VL_ATTR_OPEN_BY_IDX: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + char *obj_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 aapl_id = va_arg (arguments, hid_t); + hid_t lapl_id = va_arg (arguments, hid_t); + H5G_loc_t loc; /* Object location */ + + 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, 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_id = H5I_register(H5I_ATTR, attr, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } + +done: + /* Cleanup on failure */ + if(H5VL_ATTR_OPEN_BY_IDX == generic_type && ret_value < 0) + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_generic() */ diff --git a/src/H5VLnative.h b/src/H5VLnative.h new file mode 100644 index 0000000..75ff687 --- /dev/null +++ b/src/H5VLnative.h @@ -0,0 +1,38 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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); + +#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..fc5d7d5 --- /dev/null +++ b/src/H5VLprivate.h @@ -0,0 +1,102 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 */ +/****************************/ +/* type of the ID passed to users */ +typedef struct H5VL_id_wrapper_t { + hid_t obj_id; /* actual id for object */ + H5VL_class_t *vol_plugin; /* pointer to the VOL structure */ +} H5VL_id_wrapper_t; + +/*****************************/ +/* 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 hsize_t H5VL_sb_size(H5F_t *file); +H5_DLL hid_t H5VL_register(const void *cls, size_t size, hbool_t app_ref); + +H5_DLL herr_t H5VL_replace_with_uids(hid_t *oid_list, ssize_t num_ids); +H5_DLL int H5VL_inc_ref_uid(hid_t fid, hbool_t app_ref); + +H5_DLL hid_t H5VL_file_open(const char *name, unsigned flags, hid_t fapl_id); +H5_DLL hid_t H5VL_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); +H5_DLL herr_t H5VL_file_close(hid_t file_id); +H5_DLL herr_t H5VL_file_flush(hid_t file_id, H5F_scope_t scope); +H5_DLL herr_t H5VL_file_get(hid_t uid, H5VL_file_get_t get_type, ...); + +H5_DLL hid_t H5VL_attr_create(hid_t loc_id, const char *attr_name, hid_t acpl_id, hid_t aapl_id); +H5_DLL hid_t H5VL_attr_open(hid_t loc_id, void *location, const char *name, hid_t aapl_id); +H5_DLL herr_t H5VL_attr_read(hid_t attr_id, hid_t dtype_id, void *buf); +H5_DLL herr_t H5VL_attr_write(hid_t attr_id, hid_t dtype_id, const void *buf); +H5_DLL herr_t H5VL_attr_get(hid_t id, H5VL_attr_get_t get_type, ...); +H5_DLL herr_t H5VL_attr_generic(hid_t id, H5VL_attr_generic_t generic_type, ...); +H5_DLL herr_t H5VL_attr_close(hid_t attr_id); + +H5_DLL hid_t H5VL_dataset_create(hid_t uid, const char *name, hid_t dcpl_id, hid_t dapl_id); +H5_DLL hid_t H5VL_dataset_open(hid_t uid, const char *name, hid_t dapl_id); +H5_DLL herr_t H5VL_dataset_close(hid_t uid); +H5_DLL herr_t H5VL_dataset_read(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); +H5_DLL herr_t H5VL_dataset_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf); +H5_DLL herr_t H5VL_dataset_set_extent(hid_t uid, const hsize_t size[]); +H5_DLL herr_t H5VL_dataset_get(hid_t uid, H5VL_dataset_get_t get_type, ...); + +H5_DLL herr_t H5VL_datatype_commit(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id); +H5_DLL hid_t H5VL_datatype_open(hid_t loc_id, const char *name, hid_t tapl_id); + +H5_DLL hid_t H5VL_group_create(hid_t uid, const char *name, hid_t gcpl_id, hid_t gapl_id); +H5_DLL hid_t H5VL_group_open(hid_t uid, const char *name, hid_t gapl_id); +H5_DLL herr_t H5VL_group_close(hid_t uid); +H5_DLL herr_t H5VL_group_get(hid_t uid, H5VL_group_get_t get_type, ...); + +H5_DLL herr_t H5VL_link_create(H5VL_link_create_type_t create_type, hid_t loc_id, + const char *link_name, hid_t lcpl_id, hid_t lapl_id); +H5_DLL herr_t H5VL_link_move(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id); +H5_DLL herr_t H5VL_link_delete(hid_t loc_id, const char *name, hid_t lapl_id); + +H5_DLL hid_t H5VL_object_open_by_loc(hid_t uid, void *obj_loc, hid_t lapl_id); +H5_DLL herr_t H5VL_object_close(hid_t uid); +H5_DLL herr_t H5VL_object_get(hid_t uid, H5VL_object_get_t get_type, ...); +H5_DLL herr_t H5VL_object_lookup(hid_t uid, H5VL_object_lookup_t lookup_type, ...); + +H5_DLL herr_t H5VL_fapl_open(struct H5P_genplist_t *plist, H5VL_class_t *vol_cls); +H5_DLL herr_t H5VL_fapl_close(H5VL_class_t *vol_cls); + +#endif /* _H5VLprivate_H */ diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h new file mode 100644 index 0000000..f1d56d3 --- /dev/null +++ b/src/H5VLpublic.h @@ -0,0 +1,197 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 "H5public.h" +#include "H5Fpublic.h" +#include "H5Lpublic.h" + +/* 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_SIZE = 2, /*file size */ + H5VL_FILE_GET_FREE_SPACE = 3, /*file freespace */ + H5VL_FILE_GET_INFO = 4, /*file info */ + H5VL_FILE_GET_INTENT = 5, /*file intent */ + H5VL_FILE_GET_NAME = 6, /*file name */ + H5VL_FILE_GET_OBJ_COUNT = 7, /*object count in file */ + H5VL_FILE_GET_OBJ_IDS = 8, /*object ids in file */ + H5VL_FILE_GET_VFD_HANDLE = 9, /*file VFD handle */ + H5VL_FILE_GET_MDC_CONF = 10, /*file metadata cache configuration */ + H5VL_FILE_GET_MDC_HR = 11, /*file metadata cache hit rate */ + H5VL_FILE_GET_MDC_SIZE = 12, /*file metadata cache size */ + H5VL_FILE_GET_FREE_SECTIONS = 13 /*file free selections */ +} H5VL_file_get_t; + +/* types for all attr get API routines */ +typedef enum H5VL_attr_get_t { + H5VL_ATTR_GET_SPACE = 0, /* dataspace */ + H5VL_ATTR_GET_TYPE = 1, /* datatype */ + H5VL_ATTR_GET_ACPL = 2, /* creation property list */ + H5VL_ATTR_GET_NAME = 3, /* access property list */ + H5VL_ATTR_GET_STORAGE_SIZE = 4, /* storage size */ + H5VL_ATTR_GET_INFO = 5 /* offset */ +} H5VL_attr_get_t; + +/* types for all attr general operations */ +typedef enum H5VL_attr_generic_t { + H5VL_ATTR_OPEN_BY_IDX = 0 /* H5Aopen_by_idx */ +} H5VL_attr_generic_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 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; + +/* types for all link get API routines */ +typedef enum H5VL_link_get_t { + H5VL_LINK_GET_INFO = 0, /*link info */ + H5VL_LINK_GET_NAME = 1, /*link name */ + H5VL_LINK_GET_VAL = 2 /*link value */ +} H5VL_link_get_t; + +/* types for all object get API routines */ +typedef enum H5VL_object_get_t { + H5VL_OBJECT_GET_INFO = 0, /*object info */ + H5VL_OBJECT_GET_COMMENT = 1 /*object comment */ +} H5VL_object_get_t; + +/* types for all object lookup API routines */ +typedef enum H5VL_object_lookup_t { + H5VL_OBJECT_LOOKUP = 0, + H5VL_OBJECT_LOOKUP_BY_NAME = 1, + H5VL_OBJECT_LOOKUP_BY_IDX = 2, + H5VL_OBJECT_LOOKUP_BY_ADDR = 3, + H5VL_OBJECT_LOOKUP_BY_REF = 4 +} H5VL_object_lookup_t; + +/* types for all object lookup API routines */ +typedef enum H5VL_link_create_type_t { + H5VL_CREATE_HARD_LINK = 0, + H5VL_CREATE_SOFT_LINK = 1, + H5VL_CREATE_UD_LINK = 2 +} H5VL_link_create_type_t; + +#define H5VL_VOL_DEFAULT 0 /* Default VOL plugin value */ + +/* H5F routines */ +typedef struct H5VL_file_class_t { + hid_t (*create)(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); + hid_t (*open) (const char *name, unsigned flags, hid_t fapl_id); + herr_t (*flush) (hid_t file_id, H5F_scope_t scope); + herr_t (*get) (hid_t file_id, H5VL_file_get_t get_type, va_list arguments); + herr_t (*close) (hid_t file_id); +} H5VL_file_class_t; + +/* H5D routines */ +typedef struct H5VL_dataset_class_t { + hid_t (*create)(hid_t loc_id, const char *name, hid_t dcpl_id, hid_t dapl_id); + hid_t (*open) (hid_t loc_id, const char *name, hid_t dapl_id); + herr_t (*read) (hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, + hid_t xfer_plist_id, void * buf); + herr_t (*write) (hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, + hid_t xfer_plist_id, const void * buf ); + herr_t (*set_extent) (hid_t uid, const hsize_t size[]); + herr_t (*get) (hid_t file_id, H5VL_dataset_get_t get_type, va_list arguments); + herr_t (*close) (hid_t dataset_id); +} H5VL_dataset_class_t; + +/* H5A routines */ +typedef struct H5VL_attr_class_t { + hid_t (*create)(hid_t loc_id, const char *attr_name, hid_t acpl_id, hid_t aapl_id); + hid_t (*open) (hid_t loc_id, void *location, const char *attr_name, hid_t aapl_id); + herr_t (*read) (hid_t attr_id, hid_t mem_type_id, void *buf); + herr_t (*write) (hid_t attr_id, hid_t mem_type_id, const void *buf); + herr_t (*delete)(hid_t loc_id, const char *attr_name); + herr_t (*get) (hid_t file_id, H5VL_attr_get_t get_type, va_list arguments); + herr_t (*generic)(hid_t id, H5VL_attr_generic_t generic_type, va_list arguments); + herr_t (*close) (hid_t attr_id); +} H5VL_attr_class_t; + +/* H5T routines*/ +typedef struct H5VL_datatype_class_t { + herr_t (*commit)(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 (*open) (hid_t loc_id, const char * name, hid_t tapl_id); +}H5VL_datatype_class_t; + +/* H5L routines */ +typedef struct H5VL_link_class_t { + herr_t (*create)(H5VL_link_create_type_t create_type, hid_t link_loc_id, const char *link_name, + hid_t lcpl_id, hid_t lapl_id); + herr_t (*move) (hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dest_name, hbool_t copy_flag, hid_t lcpl, hid_t lapl); + herr_t (*get) (hid_t loc_id, H5VL_link_get_t get_type, va_list arguments); + herr_t (*delete)(hid_t loc_id, const char *name, hid_t lapl_id); +} H5VL_link_class_t; + +/* H5G routines */ +typedef struct H5VL_group_class_t { + hid_t (*create)(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id); + hid_t (*open) (hid_t loc_id, const char *name, hid_t gapl_id); + herr_t (*get) (hid_t file_id, H5VL_group_get_t get_type, va_list arguments); + herr_t (*close) (hid_t group_id); +} H5VL_group_class_t; + +/* H5O routines */ +typedef struct H5VL_object_class_t { + hid_t (*open) (hid_t loc_id, void *obj_loc, hid_t lapl_id); + herr_t (*move) (hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dest_name, hid_t lcpl, hid_t lapl); + herr_t (*copy) (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 ); + herr_t (*lookup)(hid_t loc_id, H5VL_object_lookup_t lookup_type, va_list arguments); + herr_t (*get) (hid_t loc_id, H5VL_object_get_t get_type, va_list arguments); + herr_t (*close) (hid_t obj_id); +} H5VL_object_class_t; + +/* Class information for each VOL driver */ +typedef struct H5VL_class_t { + const char *name; + unsigned nrefs; /* Ref count for times struct is pointed to */ + herr_t (*terminate)(void); + H5VL_attr_class_t attr_cls; + H5VL_datatype_class_t datatype_cls; + H5VL_dataset_class_t dataset_cls; + H5VL_group_class_t group_cls; + H5VL_file_class_t file_cls; + H5VL_link_class_t link_cls; + H5VL_object_class_t object_cls; +} H5VL_class_t; + +/* Function prototypes */ +H5_DLL hid_t H5VLregister(const H5VL_class_t *cls); +H5_DLL herr_t H5VLunregister(hid_t driver_id); + +#endif /* _H5VLpublic_H */ diff --git a/src/H5config.h.in b/src/H5config.h.in index a2059f5..27d317c 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 37480cb..0bb8e3e 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1537,6 +1537,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 d42af98..fad0241 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,6 +59,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.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 H5VLnative.c H5VLdummy.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 \ @@ -115,6 +116,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 H5VLdummy.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 37dc102..6efe7c4 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -110,43 +110,44 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.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 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 + H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5VL.lo H5VLnative.lo \ + H5VLdummy.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 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_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) @@ -518,6 +519,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.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 H5VLnative.c H5VLdummy.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 \ @@ -574,6 +576,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 H5VLdummy.h \ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h @@ -952,6 +955,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)/H5VLdummy.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@ |