summaryrefslogtreecommitdiffstats
path: root/src/H5VLnative.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5VLnative.c')
-rw-r--r--src/H5VLnative.c559
1 files changed, 559 insertions, 0 deletions
diff --git a/src/H5VLnative.c b/src/H5VLnative.c
new file mode 100644
index 0000000..616ca60
--- /dev/null
+++ b/src/H5VLnative.c
@@ -0,0 +1,559 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: The native VOL connector where access is to a single HDF5 file
+ * using HDF5 VFDs.
+ */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Aprivate.h" /* Attributes */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* Files */
+#include "H5Gprivate.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Tprivate.h" /* Datatypes */
+#include "H5VLprivate.h" /* Virtual Object Layer */
+
+#include "H5VLnative_private.h" /* Native VOL connector */
+
+
+/* The VOL connector identification number */
+static hid_t H5VL_NATIVE_ID_g = H5I_INVALID_HID;
+
+/* Prototypes */
+static herr_t H5VL__native_term(void);
+
+/* Native VOL connector class struct */
+static const H5VL_class_t H5VL_native_cls_g = {
+ H5VL_NATIVE_VERSION, /* version */
+ H5VL_NATIVE_VALUE, /* value */
+ H5VL_NATIVE_NAME, /* name */
+ 0, /* capability flags */
+ NULL, /* initialize */
+ H5VL__native_term, /* terminate */
+ { /* info_cls */
+ (size_t)0, /* info size */
+ NULL, /* info copy */
+ NULL, /* info compare */
+ NULL, /* info free */
+ NULL, /* info to str */
+ NULL /* str to info */
+ },
+ { /* wrap_cls */
+ NULL, /* get_object */
+ NULL, /* get_wrap_ctx */
+ NULL, /* wrap_object */
+ NULL, /* unwrap_object */
+ NULL /* free_wrap_ctx */
+ },
+ { /* attribute_cls */
+ H5VL__native_attr_create, /* create */
+ H5VL__native_attr_open, /* open */
+ H5VL__native_attr_read, /* read */
+ H5VL__native_attr_write, /* write */
+ H5VL__native_attr_get, /* get */
+ H5VL__native_attr_specific, /* specific */
+ H5VL__native_attr_optional, /* optional */
+ H5VL__native_attr_close /* close */
+ },
+ { /* dataset_cls */
+ H5VL__native_dataset_create, /* create */
+ H5VL__native_dataset_open, /* open */
+ H5VL__native_dataset_read, /* read */
+ H5VL__native_dataset_write, /* write */
+ H5VL__native_dataset_get, /* get */
+ H5VL__native_dataset_specific, /* specific */
+ H5VL__native_dataset_optional, /* optional */
+ H5VL__native_dataset_close /* close */
+ },
+ { /* datatype_cls */
+ H5VL__native_datatype_commit, /* commit */
+ H5VL__native_datatype_open, /* open */
+ H5VL__native_datatype_get, /* get */
+ H5VL__native_datatype_specific, /* specific */
+ NULL, /* optional */
+ H5VL__native_datatype_close /* close */
+ },
+ { /* file_cls */
+ H5VL__native_file_create, /* create */
+ H5VL__native_file_open, /* open */
+ H5VL__native_file_get, /* get */
+ H5VL__native_file_specific, /* specific */
+ H5VL__native_file_optional, /* optional */
+ H5VL__native_file_close /* close */
+ },
+ { /* group_cls */
+ H5VL__native_group_create, /* create */
+ H5VL__native_group_open, /* open */
+ H5VL__native_group_get, /* get */
+ H5VL__native_group_specific, /* specific */
+ H5VL__native_group_optional, /* optional */
+ H5VL__native_group_close /* close */
+ },
+ { /* link_cls */
+ H5VL__native_link_create, /* create */
+ H5VL__native_link_copy, /* copy */
+ H5VL__native_link_move, /* move */
+ H5VL__native_link_get, /* get */
+ H5VL__native_link_specific, /* specific */
+ NULL /* optional */
+ },
+ { /* object_cls */
+ H5VL__native_object_open, /* open */
+ H5VL__native_object_copy, /* copy */
+ H5VL__native_object_get, /* get */
+ H5VL__native_object_specific, /* specific */
+ H5VL__native_object_optional /* optional */
+ },
+ { /* introspect_cls */
+ H5VL__native_introspect_get_conn_cls, /* get_conn_cls */
+ H5VL__native_introspect_opt_query, /* opt_query */
+ },
+ { /* request_cls */
+ NULL, /* wait */
+ NULL, /* notify */
+ NULL, /* cancel */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* free */
+ },
+ { /* blob_cls */
+ H5VL__native_blob_put, /* put */
+ H5VL__native_blob_get, /* get */
+ H5VL__native_blob_specific, /* specific */
+ NULL /* optional */
+ },
+ { /* token_cls */
+ H5VL__native_token_cmp, /* cmp */
+ H5VL__native_token_to_str, /* to_str */
+ H5VL__native_str_to_token /* from_str */
+ },
+ NULL /* optional */
+};
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_native_register
+ *
+ * Purpose: Register the native VOL connector and retrieve an ID for it.
+ *
+ * Return: Success: The ID for the native connector
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5VL_native_register(void)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Register the native VOL connector, if it isn't already */
+ if(H5I_INVALID_HID == H5VL_NATIVE_ID_g)
+ if((H5VL_NATIVE_ID_g = H5VL_register_connector(&H5VL_native_cls_g, TRUE, H5P_VOL_INITIALIZE_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, H5I_INVALID_HID, "can't create ID for native VOL connector")
+
+ /* Set return value */
+ ret_value = H5VL_NATIVE_ID_g;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_native_register() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__native_term
+ *
+ * Purpose: Shut down the native VOL
+ *
+ * Returns: SUCCEED (Can't fail)
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__native_term(void)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Reset VOL ID */
+ H5VL_NATIVE_ID_g = H5I_INVALID_HID;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL__native_term() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__native_introspect_get_conn_cls
+ *
+ * Purpose: Query the connector class.
+ *
+ * Note: This routine is in this file so that it can return the address
+ * of the staticly declared class struct.
+ *
+ * Returns: SUCCEED (Can't fail)
+ *
+ *---------------------------------------------------------------------------
+ */
+herr_t
+H5VL__native_introspect_get_conn_cls(void H5_ATTR_UNUSED *obj,
+ H5VL_get_conn_lvl_t H5_ATTR_UNUSED lvl, const H5VL_class_t **conn_cls)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity check */
+ HDassert(conn_cls);
+
+ /* Retrieve the native VOL connector class */
+ *conn_cls = &H5VL_native_cls_g;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL__native_introspect_get_conn_cls() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_native_get_file_addr_len
+ *
+ * Purpose: Convenience function to get a file's address length from a
+ * location ID. Useful when you have to encode/decode addresses
+ * to/from tokens.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_native_get_file_addr_len(hid_t loc_id, size_t *addr_len)
+{
+ H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */
+ void *vol_obj = NULL; /* VOL Object of loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* check arguments */
+ HDassert(addr_len);
+
+ /* Get object type */
+ if((vol_obj_type = H5I_get_type(loc_id)) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Retrieve underlying VOL object */
+ if(NULL == (vol_obj = H5VL_object(loc_id)))
+ HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Retrieve file address length */
+ if(H5VL__native_get_file_addr_len(vol_obj, vol_obj_type, addr_len) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get file address length")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_native_get_file_addr_len() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__native_get_file_addr_len
+ *
+ * Purpose: Convenience function to get a file's address length from a
+ * VOL object. Useful when you have to encode/decode addresses
+ * to/from tokens.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL__native_get_file_addr_len(void *obj, H5I_type_t obj_type, size_t *addr_len)
+{
+ H5F_t *file = NULL; /* File stuct pointer */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* check arguments */
+ HDassert(obj);
+ HDassert(addr_len);
+
+ /* Retrieve file from the VOL object */
+ if(H5VL_native_get_file_struct(obj, obj_type, &file) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get file from VOL object")
+
+ /* Get the length of an address in this file */
+ *addr_len = H5F_SIZEOF_ADDR(file);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__native_get_file_addr_len() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VLnative_addr_to_token
+ *
+ * Purpose: Converts a native VOL haddr_t address to an abstract VOL token.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VLnative_addr_to_token(hid_t loc_id, haddr_t addr, H5O_token_t *token)
+{
+ H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */
+ void *vol_obj = NULL; /* VOL Object of loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "ia*k", loc_id, addr, token);
+
+ /* Check args */
+ if(NULL == token)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "token pointer can't be NULL")
+
+ /* Get object type */
+ if((vol_obj_type = H5I_get_type(loc_id)) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Retrieve underlying VOL object */
+ if(NULL == (vol_obj = H5VL_object(loc_id)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object")
+
+#ifndef NDEBUG
+ {
+ H5VL_object_t *vol_obj_container;
+ hbool_t is_native_vol_obj;
+
+ /* Get the location object */
+ if(NULL == (vol_obj_container = (H5VL_object_t *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Make sure that the VOL object is a native connector object */
+ if(H5VL_object_is_native(vol_obj_container, &is_native_vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object")
+
+ HDassert(is_native_vol_obj && "not a native VOL connector object");
+ }
+#endif
+
+ /* Convert the haddr_t to an object token */
+ if(H5VL_native_addr_to_token(vol_obj, vol_obj_type, addr, token) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "couldn't serialize haddr_t into object token")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5VLnative_addr_to_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_native_addr_to_token
+ *
+ * Purpose: Converts a native VOL haddr_t address to an abstract VOL token.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_native_addr_to_token(void *obj, H5I_type_t obj_type, haddr_t addr, H5O_token_t *token)
+{
+ uint8_t *p;
+ size_t addr_len = 0; /* Size of haddr_t */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(obj);
+ HDassert(token);
+
+ /* Get the length of an haddr_t in the file */
+ if(H5VL__native_get_file_addr_len(obj, obj_type, &addr_len) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get length of haddr_t from VOL object")
+
+ /* Ensure that token is initialized */
+ HDmemset(token, 0, sizeof(H5O_token_t));
+
+ /* Encode token */
+ p = (uint8_t *)token;
+ H5F_addr_encode_len(addr_len, &p, addr);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_native_addr_to_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VLnative_token_to_addr
+ *
+ * Purpose: Converts an abstract VOL token to a native VOL haddr_t address.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VLnative_token_to_addr(hid_t loc_id, H5O_token_t token, haddr_t *addr)
+{
+ H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */
+ void *vol_obj = NULL; /* VOL Object of loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "ik*a", loc_id, token, addr);
+
+ /* Check args */
+ if(NULL == addr)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr pointer can't be NULL")
+
+ /* Get object type */
+ if((vol_obj_type = H5I_get_type(loc_id)) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Retrieve underlying VOL object */
+ if(NULL == (vol_obj = H5VL_object(loc_id)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object")
+
+#ifndef NDEBUG
+ {
+ H5VL_object_t *vol_obj_container;
+ hbool_t is_native_vol_obj;
+
+ /* Get the location object */
+ if(NULL == (vol_obj_container = (H5VL_object_t *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Make sure that the VOL object is a native connector object */
+ if(H5VL_object_is_native(vol_obj_container, &is_native_vol_obj) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object")
+
+ HDassert(is_native_vol_obj && "not a native VOL connector object");
+ }
+#endif
+
+ /* Convert the object token to an haddr_t */
+ if(H5VL_native_token_to_addr(vol_obj, vol_obj_type, token, addr) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "couldn't deserialize object token into haddr_t")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5VLnative_token_to_addr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_native_token_to_addr
+ *
+ * Purpose: Converts an abstract VOL token to a native VOL haddr_t address.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_native_token_to_addr(void *obj, H5I_type_t obj_type, H5O_token_t token, haddr_t *addr)
+{
+ const uint8_t *p;
+ size_t addr_len = 0; /* Size of haddr_t */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(obj);
+ HDassert(addr);
+
+ /* Get the length of an haddr_t in the file */
+ if(H5VL__native_get_file_addr_len(obj, obj_type, &addr_len) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get length of haddr_t from VOL object")
+
+ /* Decode token */
+ p = (const uint8_t *)&token;
+ H5F_addr_decode_len(addr_len, &p, addr);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_native_token_to_addr() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_native_get_file_struct
+ *
+ * Purpose: Utility routine to get file struct for an object
+ *
+ * Returns: SUCCEED/FAIL
+ *
+ *---------------------------------------------------------------------------
+ */
+herr_t
+H5VL_native_get_file_struct(void *obj, H5I_type_t type, H5F_t **file)
+{
+ H5O_loc_t *oloc = NULL; /* Object location for ID */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL);
+
+ *file = NULL;
+
+ switch(type) {
+ case H5I_FILE:
+ *file = (H5F_t *)obj;
+ break;
+
+ case H5I_GROUP:
+ oloc = H5G_oloc((H5G_t *)obj);
+ break;
+
+ case H5I_DATATYPE:
+ oloc = H5T_oloc((H5T_t *)obj);
+ break;
+
+ case H5I_DATASET:
+ oloc = H5D_oloc((H5D_t *)obj);
+ break;
+
+ case H5I_ATTR:
+ oloc = H5A_oloc((H5A_t *)obj);
+ break;
+
+ case H5I_MAP:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "maps not supported in native VOL connector")
+
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_DATASPACE:
+ 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_SPACE_SEL_ITER:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+ } /* end switch */
+
+ /* Set return value for objects (not files) */
+ if(oloc)
+ *file = oloc->file;
+
+ /* Couldn't find a file struct */
+ if(!*file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not associated with a file")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL_native_get_file_struct */
+