mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
* Remove hbool_t from the public API This was previously removed from the source code, but the API calls retained hbool_t in the public API calls. This commit removes hbool_t from the public APIs. hbool_t is retained as a typedef for bool in H5public.h so existing code doesn't break.
1042 lines
38 KiB
C
1042 lines
38 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* 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 LICENSE file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://www.hdfgroup.org/licenses. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*
|
|
* Purpose: The Virtual Object Layer as described in documentation.
|
|
* The purpose 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 */
|
|
/****************/
|
|
|
|
#include "H5VLmodule.h" /* This source code file is part of the H5VL module */
|
|
|
|
/***********/
|
|
/* Headers */
|
|
/***********/
|
|
|
|
#include "H5private.h" /* Generic Functions */
|
|
#include "H5Eprivate.h" /* Error handling */
|
|
#include "H5Iprivate.h" /* IDs */
|
|
#include "H5Pprivate.h" /* Property lists */
|
|
#include "H5Tprivate.h" /* Datatypes */
|
|
#include "H5VLpkg.h" /* Virtual Object Layer */
|
|
|
|
/* VOL connectors */
|
|
#include "H5VLnative_private.h" /* Native VOL connector */
|
|
|
|
/****************/
|
|
/* Local Macros */
|
|
/****************/
|
|
|
|
/******************/
|
|
/* Local Typedefs */
|
|
/******************/
|
|
|
|
/********************/
|
|
/* Local Prototypes */
|
|
/********************/
|
|
|
|
/*********************/
|
|
/* Package Variables */
|
|
/*********************/
|
|
|
|
/*****************************/
|
|
/* Library Private Variables */
|
|
/*****************************/
|
|
|
|
/*******************/
|
|
/* Local Variables */
|
|
/*******************/
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLregister_connector
|
|
*
|
|
* Purpose: Registers a new VOL connector as a member of the virtual object
|
|
* layer class.
|
|
*
|
|
* VIPL_ID is a VOL initialization property list which must be
|
|
* created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
|
|
*
|
|
* Return: Success: A VOL connector ID which is good until the
|
|
* library is closed or the connector is
|
|
* unregistered.
|
|
*
|
|
* Failure: H5I_INVALID_HID
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id)
|
|
{
|
|
H5VL_connector_t *connector = NULL;
|
|
hid_t ret_value = H5I_INVALID_HID; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5I_INVALID_HID)
|
|
|
|
/* Check VOL initialization property list */
|
|
if (H5P_DEFAULT == vipl_id)
|
|
vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
|
|
else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list");
|
|
|
|
/* Register connector */
|
|
if (NULL == (connector = H5VL__register_connector_by_class(cls, vipl_id)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL class");
|
|
|
|
/* Get ID for connector */
|
|
if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector");
|
|
|
|
done:
|
|
if (ret_value < 0)
|
|
/* Decrement refcount on connector */
|
|
if (connector && H5VL_conn_dec_rc(connector) < 0)
|
|
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID,
|
|
"unable to decrement ref count on VOL connector");
|
|
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLregister_connector() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLregister_connector_by_name
|
|
*
|
|
* Purpose: Registers a new VOL connector as a member of the virtual object
|
|
* layer class.
|
|
*
|
|
* VIPL_ID is a VOL initialization property list which must be
|
|
* created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
|
|
*
|
|
* Return: Success: A VOL connector ID which is good until the
|
|
* library is closed or the connector is
|
|
* unregistered.
|
|
*
|
|
* Failure: H5I_INVALID_HID
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLregister_connector_by_name(const char *name, hid_t vipl_id)
|
|
{
|
|
H5VL_connector_t *connector = NULL;
|
|
hid_t ret_value = H5I_INVALID_HID; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5I_INVALID_HID)
|
|
|
|
/* Check arguments */
|
|
if (!name)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "null VOL connector name is disallowed");
|
|
if (0 == strlen(name))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID,
|
|
"zero-length VOL connector name is disallowed");
|
|
|
|
/* Check VOL initialization property list */
|
|
if (H5P_DEFAULT == vipl_id)
|
|
vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
|
|
else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list");
|
|
|
|
/* Register connector */
|
|
if (NULL == (connector = H5VL__register_connector_by_name(name, vipl_id)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector");
|
|
|
|
/* Get ID for connector */
|
|
if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID");
|
|
|
|
done:
|
|
if (ret_value < 0)
|
|
/* Decrement refcount on connector */
|
|
if (connector && H5VL_conn_dec_rc(connector) < 0)
|
|
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID,
|
|
"unable to decrement ref count on VOL connector");
|
|
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLregister_connector_by_name() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLregister_connector_by_value
|
|
*
|
|
* Purpose: Registers a new VOL connector as a member of the virtual object
|
|
* layer class.
|
|
*
|
|
* VIPL_ID is a VOL initialization property list which must be
|
|
* created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
|
|
*
|
|
* Return: Success: A VOL connector ID which is good until the
|
|
* library is closed or the connector is
|
|
* unregistered.
|
|
*
|
|
* Failure: H5I_INVALID_HID
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLregister_connector_by_value(H5VL_class_value_t value, hid_t vipl_id)
|
|
{
|
|
H5VL_connector_t *connector = NULL;
|
|
hid_t ret_value = H5I_INVALID_HID; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5I_INVALID_HID)
|
|
|
|
/* Check arguments */
|
|
if (value < 0)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID,
|
|
"negative VOL connector value is disallowed");
|
|
|
|
/* Check VOL initialization property list */
|
|
if (H5P_DEFAULT == vipl_id)
|
|
vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
|
|
else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list");
|
|
|
|
/* Register connector */
|
|
if (NULL == (connector = H5VL__register_connector_by_value(value, vipl_id)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector");
|
|
|
|
/* Get ID for connector */
|
|
if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID");
|
|
|
|
done:
|
|
if (ret_value < 0)
|
|
/* Decrement refcount on connector */
|
|
if (connector && H5VL_conn_dec_rc(connector) < 0)
|
|
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID,
|
|
"unable to decrement ref count on VOL connector");
|
|
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLregister_connector_by_value() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLis_connector_registered_by_name
|
|
*
|
|
* Purpose: Tests whether a VOL class has been registered or not
|
|
* according to a supplied connector name.
|
|
*
|
|
* Return: >0 if a VOL connector with that name has been registered
|
|
* 0 if a VOL connector with that name has NOT been registered
|
|
* <0 on errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
htri_t
|
|
H5VLis_connector_registered_by_name(const char *name)
|
|
{
|
|
htri_t ret_value = false; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check if connector with this name is registered */
|
|
if ((ret_value = H5VL__is_connector_registered_by_name(name)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLis_connector_registered_by_name() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLis_connector_registered_by_value
|
|
*
|
|
* Purpose: Tests whether a VOL class has been registered or not
|
|
* according to a supplied connector value (ID).
|
|
*
|
|
* Return: >0 if a VOL connector with that value has been registered
|
|
* 0 if a VOL connector with that value hasn't been registered
|
|
* <0 on errors
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
htri_t
|
|
H5VLis_connector_registered_by_value(H5VL_class_value_t connector_value)
|
|
{
|
|
htri_t ret_value = false;
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check if connector with this value is registered */
|
|
if ((ret_value = H5VL__is_connector_registered_by_value(connector_value)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLis_connector_registered_by_value() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLget_connector_id
|
|
*
|
|
* Purpose: Retrieves the VOL connector ID for a given object ID.
|
|
*
|
|
* Return: A valid VOL connector ID. This ID will need to be closed
|
|
* using H5VLclose().
|
|
*
|
|
* H5I_INVALID_HID on error.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLget_connector_id(hid_t obj_id)
|
|
{
|
|
H5VL_object_t *vol_obj = NULL;
|
|
hid_t ret_value = H5I_INVALID_HID; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5I_INVALID_HID)
|
|
|
|
/* Get the underlying VOL object for the object ID */
|
|
if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier");
|
|
|
|
/* Register an ID for the connector */
|
|
if ((ret_value = H5VL_conn_register(vol_obj->connector)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't get VOL ID");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLget_connector_id() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLget_connector_id_by_name
|
|
*
|
|
* Purpose: Retrieves the ID for a registered VOL connector.
|
|
*
|
|
* Return: A valid VOL connector ID if a connector by that name has
|
|
* been registered. This ID will need to be closed using
|
|
* H5VLclose().
|
|
*
|
|
* H5I_INVALID_HID on error or if a VOL connector of that
|
|
* name has not been registered.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLget_connector_id_by_name(const char *name)
|
|
{
|
|
H5VL_connector_t *connector = NULL;
|
|
hid_t ret_value = H5I_INVALID_HID; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5I_INVALID_HID)
|
|
|
|
/* Get connector ID with this name */
|
|
if (NULL == (connector = H5VL__get_connector_by_name(name)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector");
|
|
|
|
/* Get ID for connector */
|
|
if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID");
|
|
|
|
done:
|
|
if (ret_value < 0)
|
|
/* Decrement refcount on connector */
|
|
if (connector && H5VL_conn_dec_rc(connector) < 0)
|
|
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID,
|
|
"unable to decrement ref count on VOL connector");
|
|
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLget_connector_id_by_name() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLget_connector_id_by_value
|
|
*
|
|
* Purpose: Retrieves the ID for a registered VOL connector.
|
|
*
|
|
* Return: A valid VOL connector ID if a connector with that value has
|
|
* been registered. This ID will need to be closed using
|
|
* H5VLclose().
|
|
*
|
|
* H5I_INVALID_HID on error or if a VOL connector with that
|
|
* value has not been registered.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLget_connector_id_by_value(H5VL_class_value_t connector_value)
|
|
{
|
|
H5VL_connector_t *connector = NULL;
|
|
hid_t ret_value = H5I_INVALID_HID; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5I_INVALID_HID)
|
|
|
|
/* Get connector ID with this value */
|
|
if (NULL == (connector = H5VL__get_connector_by_value(connector_value)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector");
|
|
|
|
/* Get ID for connector */
|
|
if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID");
|
|
|
|
done:
|
|
if (ret_value < 0)
|
|
/* Decrement refcount on connector */
|
|
if (connector && H5VL_conn_dec_rc(connector) < 0)
|
|
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID,
|
|
"unable to decrement ref count on VOL connector");
|
|
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLget_connector_id_by_value() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLget_connector_name
|
|
*
|
|
* Purpose: Returns the connector name for the VOL associated with the
|
|
* object or file ID.
|
|
*
|
|
* This works like other calls where the caller must provide a
|
|
* buffer of the appropriate size for the library to fill in.
|
|
* i.e., passing in a NULL pointer for NAME will return the
|
|
* required size of the buffer.
|
|
*
|
|
* Return: Success: The length of the connector name
|
|
*
|
|
* Failure: Negative
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
ssize_t
|
|
H5VLget_connector_name(hid_t obj_id, char *name /*out*/, size_t size)
|
|
{
|
|
H5VL_object_t *vol_obj;
|
|
ssize_t ret_value = -1;
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Get the object pointer */
|
|
if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid VOL identifier");
|
|
|
|
/* Call internal routine */
|
|
ret_value = (ssize_t)H5VL__get_connector_name(vol_obj->connector, name, size);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLget_connector_name() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLclose
|
|
*
|
|
* Purpose: Closes a VOL connector ID. This in no way affects
|
|
* file access property lists which have been defined to use
|
|
* this VOL connector or files which are already opened under with
|
|
* this connector.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLclose(hid_t vol_id)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check args */
|
|
if (NULL == H5I_object_verify(vol_id, H5I_VOL))
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector");
|
|
|
|
/* Decrement the ref count on the ID, possibly releasing the VOL connector */
|
|
if (H5I_dec_app_ref(vol_id) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to close VOL connector ID");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLclose() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLunregister_connector
|
|
*
|
|
* Purpose: Removes a VOL connector ID from the library. This in no way affects
|
|
* file access property lists which have been defined to use
|
|
* this VOL connector or files which are already opened under with
|
|
* this connector.
|
|
*
|
|
* The native VOL connector cannot be unregistered and attempts
|
|
* to do so are considered an error.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLunregister_connector(hid_t vol_id)
|
|
{
|
|
H5VL_connector_t *native, *connector;
|
|
int cmp_value; /* Comparison result */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check arguments */
|
|
if (NULL == (connector = H5I_object_verify(vol_id, H5I_VOL)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID");
|
|
|
|
/* For the time being, we disallow unregistering the native VOL connector */
|
|
native = H5VL_NATIVE_conn_g;
|
|
if (H5VL_cmp_connector_cls(&cmp_value, connector->cls, native->cls) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector classes");
|
|
if (0 == cmp_value)
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "unregistering the native VOL connector is not allowed");
|
|
|
|
/* The H5VL_connector_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 connector");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLunregister_connector() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLcmp_connector_cls
|
|
*
|
|
* Purpose: Compares two connector classes (based on their value field)
|
|
*
|
|
* Note: This routine is _only_ for HDF5 VOL connector authors! It is
|
|
* _not_ part of the public API for HDF5 application developers.
|
|
*
|
|
* Return: Success: Non-negative, *cmp set to a value like strcmp
|
|
*
|
|
* Failure: Negative, *cmp unset
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLcmp_connector_cls(int *cmp, hid_t connector_id1, hid_t connector_id2)
|
|
{
|
|
H5VL_connector_t *conn1, *conn2; /* Connectors for IDs */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check args and get class pointers */
|
|
if (NULL == (conn1 = H5I_object_verify(connector_id1, H5I_VOL)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
|
|
if (NULL == (conn2 = H5I_object_verify(connector_id2, H5I_VOL)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
|
|
|
|
/* Compare the two VOL connector classes */
|
|
if (H5VL_cmp_connector_cls(cmp, conn1->cls, conn2->cls) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector classes");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLcmp_connector_cls() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLwrap_register
|
|
*
|
|
* Purpose: Wrap an internal object with a "wrap context" and register an
|
|
* hid_t for the resulting object.
|
|
*
|
|
* Note: This routine is mainly targeted toward wrapping objects for
|
|
* iteration routine callbacks (i.e. the callbacks from H5Aiterate*,
|
|
* H5Literate* / H5Lvisit*, and H5Ovisit* ).
|
|
*
|
|
* type must be a VOL-managed object class (H5I_FILE,
|
|
* H5I_GROUP, H5I_DATATYPE, H5I_DATASET, H5I_MAP, or H5I_ATTR).
|
|
*
|
|
* Return: Success: Non-negative hid_t for the object.
|
|
* Failure: Negative (H5I_INVALID_HID)
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLwrap_register(void *obj, H5I_type_t type)
|
|
{
|
|
hid_t ret_value; /* Return value */
|
|
|
|
/* Use FUNC_ENTER_API_NOINIT here, so the API context doesn't get reset */
|
|
FUNC_ENTER_API_NOINIT
|
|
|
|
/* Check args */
|
|
/* Use a switch here for (hopefully) better performance than a series of
|
|
* equality checks. We could also group these types together in H5I_type_t,
|
|
* make some assertions here to guarantee that, then just check the range.
|
|
*/
|
|
switch (type) {
|
|
case H5I_FILE:
|
|
case H5I_GROUP:
|
|
case H5I_DATATYPE:
|
|
case H5I_DATASET:
|
|
case H5I_MAP:
|
|
case H5I_ATTR:
|
|
/* VOL-managed objects, call is valid */
|
|
break;
|
|
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_EVENTSET:
|
|
case H5I_NTYPES:
|
|
default:
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADRANGE, H5I_INVALID_HID, "invalid type number");
|
|
} /* end switch */
|
|
if (NULL == obj)
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, H5I_INVALID_HID, "obj is NULL");
|
|
|
|
/* Wrap the object and register an ID for it */
|
|
if ((ret_value = H5VL_wrap_register(type, obj, true)) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to wrap object");
|
|
|
|
done:
|
|
FUNC_LEAVE_API_NOINIT(ret_value)
|
|
} /* H5VLwrap_register() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLobject
|
|
*
|
|
* Purpose: Retrieve the object pointer associated with an hid_t for a
|
|
* VOL object.
|
|
*
|
|
* Note: This routine is mainly targeted toward unwrapping objects for
|
|
* testing.
|
|
*
|
|
* Return: Success: Object pointer
|
|
* Failure: NULL
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
void *
|
|
H5VLobject(hid_t id)
|
|
{
|
|
void *ret_value; /* Return value */
|
|
|
|
FUNC_ENTER_API(NULL)
|
|
|
|
/* Retrieve the object pointer for the ID */
|
|
if (NULL == (ret_value = H5VL_object(id)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to retrieve object");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLobject() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLobject_is_native
|
|
*
|
|
* Purpose: Determines whether an object ID represents a native VOL
|
|
* connector object.
|
|
*
|
|
* Return: Non-negative on success/Negative on failure
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLobject_is_native(hid_t obj_id, bool *is_native)
|
|
{
|
|
H5VL_object_t *vol_obj = NULL;
|
|
herr_t ret_value = SUCCEED;
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
if (!is_native)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "`is_native` argument is NULL");
|
|
|
|
/* Get the location object for the ID */
|
|
if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
|
|
|
|
if (H5VL_object_is_native(vol_obj, is_native) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if object is a native connector object");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLobject_is_native() */
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5VLget_file_type
|
|
*
|
|
* Purpose: Returns a copy of dtype_id with its location set to be in
|
|
* the file, with updated size, etc.
|
|
*
|
|
* Return: Non-negative on success/Negative on failure
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
hid_t
|
|
H5VLget_file_type(void *file_obj, hid_t connector_id, hid_t dtype_id)
|
|
{
|
|
H5T_t *dtype; /* unregistered type */
|
|
H5T_t *file_type = NULL; /* copied file type */
|
|
hid_t file_type_id = -1; /* copied file type id */
|
|
H5VL_connector_t *connector; /* VOL connector */
|
|
H5VL_object_t *file_vol_obj = NULL; /* VOL object for file */
|
|
hid_t ret_value = -1; /* Return value */
|
|
|
|
FUNC_ENTER_API(H5I_INVALID_HID)
|
|
|
|
/* Check args */
|
|
if (!file_obj)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "no file object supplied");
|
|
if (NULL == (dtype = H5I_object_verify(dtype_id, H5I_DATATYPE)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
|
|
if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file VOL ID");
|
|
|
|
/* Create VOL object for file if necessary (force_conv will be true if and
|
|
* only if file needs to be passed to H5T_set_loc) */
|
|
if (H5T_GET_FORCE_CONV(dtype))
|
|
if (NULL == (file_vol_obj = H5VL_new_vol_obj(H5I_FILE, file_obj, connector, true)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create VOL object");
|
|
|
|
/* Copy the datatype */
|
|
if (NULL == (file_type = H5T_copy(dtype, H5T_COPY_TRANSIENT)))
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, H5I_INVALID_HID, "unable to copy datatype");
|
|
|
|
/* Register file type id */
|
|
if ((file_type_id = H5I_register(H5I_DATATYPE, file_type, false)) < 0) {
|
|
(void)H5T_close_real(file_type);
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file datatype");
|
|
} /* end if */
|
|
|
|
/* Set the location of the datatype to be in the file */
|
|
if (H5T_set_loc(file_type, file_vol_obj, H5T_LOC_DISK) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "can't set datatype location");
|
|
|
|
/* Release our reference to file_type */
|
|
if (file_vol_obj) {
|
|
if (H5VL_free_object(file_vol_obj) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to free VOL object");
|
|
file_vol_obj = NULL;
|
|
} /* end if */
|
|
|
|
/* Set return value */
|
|
ret_value = file_type_id;
|
|
|
|
done:
|
|
/* Cleanup on error */
|
|
if (ret_value < 0) {
|
|
if (file_vol_obj && H5VL_free_object(file_vol_obj) < 0)
|
|
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to free VOL object");
|
|
if (file_type_id >= 0 && H5I_dec_ref(file_type_id) < 0)
|
|
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to close file datatype");
|
|
} /* end if */
|
|
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* end H5VLget_file_type() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLretrieve_lib_state
|
|
*
|
|
* Purpose: Retrieves a copy of the internal state of the HDF5 library,
|
|
* so that it can be restored later.
|
|
*
|
|
* Note: This routine is _only_ for HDF5 VOL connector authors! It is
|
|
* _not_ part of the public API for HDF5 application developers.
|
|
*
|
|
* Return: Success: Non-negative, *state set
|
|
* Failure: Negative, *state unset
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLretrieve_lib_state(void **state /*out*/)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
/* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
|
|
FUNC_ENTER_API_NOINIT
|
|
|
|
/* Check args */
|
|
if (NULL == state)
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer");
|
|
|
|
/* Retrieve the library state */
|
|
if (H5VL_retrieve_lib_state(state) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve library state");
|
|
|
|
done:
|
|
FUNC_LEAVE_API_NOINIT(ret_value)
|
|
} /* H5VLretrieve_lib_state() */
|
|
|
|
herr_t
|
|
H5VLopen_lib_context(void **context)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
/* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
|
|
FUNC_ENTER_API_NOINIT
|
|
|
|
/* Check args */
|
|
if (NULL == context)
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid context pointer");
|
|
|
|
/* Start a new library state */
|
|
if (H5VL_start_lib_state(context) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't start new library state");
|
|
|
|
done:
|
|
FUNC_LEAVE_API_NOINIT(ret_value)
|
|
} /* H5VLopen_lib_context() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLrestore_lib_state
|
|
*
|
|
* Purpose: Restores the internal state of the HDF5 library.
|
|
*
|
|
* Note: This routine is _only_ for HDF5 VOL connector authors! It is
|
|
* _not_ part of the public API for HDF5 application developers.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLrestore_lib_state(const void *state)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
/* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
|
|
FUNC_ENTER_API_NOINIT
|
|
|
|
/* Check args */
|
|
if (NULL == state)
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer");
|
|
|
|
/* Restore the library state */
|
|
if (H5VL_restore_lib_state(state) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't restore library state");
|
|
|
|
done:
|
|
FUNC_LEAVE_API_NOINIT(ret_value)
|
|
} /* H5VLrestore_lib_state() */
|
|
|
|
herr_t
|
|
H5VLclose_lib_context(void *context)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
/* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
|
|
FUNC_ENTER_API_NOINIT
|
|
|
|
/* Check args */
|
|
if (NULL == context)
|
|
HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid context pointer");
|
|
|
|
/* Reset the library state */
|
|
if (H5VL_finish_lib_state(context) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset library state");
|
|
|
|
done:
|
|
FUNC_LEAVE_API_NOINIT(ret_value)
|
|
} /* H5VLclose_lib_context() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLfree_lib_state
|
|
*
|
|
* Purpose: Free a retrieved library state.
|
|
*
|
|
* Note: This routine is _only_ for HDF5 VOL connector authors! It is
|
|
* _not_ part of the public API for HDF5 application developers.
|
|
*
|
|
* Note: This routine must be called as a "pair" with
|
|
* H5VLretrieve_lib_state.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLfree_lib_state(void *state)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check args */
|
|
if (NULL == state)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid state pointer");
|
|
|
|
/* Free the library state */
|
|
if (H5VL_free_lib_state(state) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free library state");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLfree_lib_state() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLquery_optional
|
|
*
|
|
* Purpose: Determine if a VOL connector supports a particular optional
|
|
* callback operation, and a general sense of the operation's
|
|
* behavior.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags /*out*/)
|
|
{
|
|
H5VL_object_t *vol_obj = NULL;
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check args */
|
|
if (NULL == flags)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid 'flags' pointer");
|
|
if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
|
|
|
|
/* Query the connector */
|
|
if (H5VL_introspect_opt_query(vol_obj, subcls, opt_type, flags) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to query VOL connector operation");
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLquery_optional() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLregister_opt_operation
|
|
*
|
|
* Purpose: Allow a VOL connector to register a new optional operation
|
|
* for a VOL object subclass. The operation name must be runtime
|
|
* unique for each operation, preferably avoiding naming clashes
|
|
* by using a Uniform Type Identifier (UTI,
|
|
*https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html)
|
|
* for each operation name. The value returned in the 'op_val'
|
|
* pointer will be unique for that VOL connector to use for its
|
|
* operation on that subclass.
|
|
*
|
|
* For example, registering a 'prefetch' operation for the
|
|
* caching VOL connector written at the ALCF at Argonne National
|
|
* Laboratory could have a UTI of: "gov.anl.alcf.cache.prefetch",
|
|
* and the "evict" operation for the same connector could have a
|
|
* UTI of: "gov.anl.alcf.cache.evict". Registering a "suspend
|
|
* background threads" operation for the asynchronous VOL connector
|
|
* written at NERSC at Lawrence Berkeley National Laboratory could
|
|
* have a UTI of: "gov.lbnl.nersc.async.suspend_bkg_threads".
|
|
*
|
|
* Note: The first 1024 values of each subclass's optional operations
|
|
* are reserved for the native VOL connector's use.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check args */
|
|
if (NULL == op_val)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer");
|
|
if (NULL == op_name)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer");
|
|
if ('\0' == *op_name)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string");
|
|
if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) ||
|
|
(H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) ||
|
|
(H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type");
|
|
|
|
/* Register the operation */
|
|
if (H5VL__register_opt_operation(subcls, op_name, op_val) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register dynamic optional operation: '%s'",
|
|
op_name);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLregister_opt_operation() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLfind_opt_operation
|
|
*
|
|
* Purpose: Look up a optional operation for a VOL object subclass, by name.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check args */
|
|
if (NULL == op_val)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer");
|
|
if (NULL == op_name)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer");
|
|
if ('\0' == *op_name)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string");
|
|
if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) ||
|
|
(H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) ||
|
|
(H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type");
|
|
|
|
/* Find the operation */
|
|
if (H5VL__find_opt_operation(subcls, op_name, op_val) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "can't find dynamic optional operation: '%s'", op_name);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLfind_opt_operation() */
|
|
|
|
/*---------------------------------------------------------------------------
|
|
* Function: H5VLunregister_opt_operation
|
|
*
|
|
* Purpose: Unregister a optional operation for a VOL object subclass, by name.
|
|
*
|
|
* Return: Success: Non-negative
|
|
* Failure: Negative
|
|
*
|
|
*---------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_API(FAIL)
|
|
|
|
/* Check args */
|
|
if (NULL == op_name)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer");
|
|
if ('\0' == *op_name)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string");
|
|
if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) ||
|
|
(H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) ||
|
|
(H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls)))
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type");
|
|
|
|
/* Unregister the operation */
|
|
if (H5VL__unregister_opt_operation(subcls, op_name) < 0)
|
|
HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "can't unregister dynamic optional operation: '%s'",
|
|
op_name);
|
|
|
|
done:
|
|
FUNC_LEAVE_API(ret_value)
|
|
} /* H5VLunregister_opt_operation() */
|