diff options
author | Jacob Smith <jake.smith@hdfgroup.org> | 2018-12-12 19:39:14 (GMT) |
---|---|---|
committer | Jacob Smith <jake.smith@hdfgroup.org> | 2018-12-12 23:26:08 (GMT) |
commit | ea7332525010ef75e27ce5800cf65dd91ba43576 (patch) | |
tree | 19f440d677555c016dacc4a2cd28aaa80961e350 /src/H5VLnative.c | |
parent | 496de6922fb13aa11a5c5efe56a3f8de157a77ad (diff) | |
parent | 6f52793adcd5a14aa63731e3c33c9737b5a04d16 (diff) | |
download | hdf5-ea7332525010ef75e27ce5800cf65dd91ba43576.zip hdf5-ea7332525010ef75e27ce5800cf65dd91ba43576.tar.gz hdf5-ea7332525010ef75e27ce5800cf65dd91ba43576.tar.bz2 |
Merge branch 'develop' into dset_ohdr_minimize
Diffstat (limited to 'src/H5VLnative.c')
-rw-r--r-- | src/H5VLnative.c | 3655 |
1 files changed, 3655 insertions, 0 deletions
diff --git a/src/H5VLnative.c b/src/H5VLnative.c new file mode 100644 index 0000000..5368d41 --- /dev/null +++ b/src/H5VLnative.c @@ -0,0 +1,3655 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. + */ + +#define H5A_FRIEND /* Suppress error about including H5Apkg */ +#define H5D_FRIEND /* Suppress error about including H5Dpkg */ +#define H5F_FRIEND /* Suppress error about including H5Fpkg */ +#define H5G_FRIEND /* Suppress error about including H5Gpkg */ +#define H5L_FRIEND /* Suppress error about including H5Lpkg */ +#define H5O_FRIEND /* Suppress error about including H5Opkg */ +#define H5R_FRIEND /* Suppress error about including H5Rpkg */ +#define H5T_FRIEND /* Suppress error about including H5Tpkg */ + + +#include "H5private.h" /* Generic Functions */ +#include "H5Apkg.h" /* Attributes */ +#include "H5Dpkg.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* Files */ +#include "H5Gpkg.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lpkg.h" /* Links */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Opkg.h" /* Object headers */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5Rpkg.h" /* References */ +#include "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5Tpkg.h" /* Datatypes */ +#include "H5VLprivate.h" /* Virtual Object Layer */ +#include "H5VLnative.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); + +/* Atrribute callbacks */ +static void *H5VL__native_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req); +static void *H5VL__native_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, hid_t aapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req); +static herr_t H5VL__native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req); +static herr_t H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_attr_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_attr_close(void *attr, hid_t dxpl_id, void **req); + +/* Dataset callbacks */ +static void *H5VL__native_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req); +static void *H5VL__native_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t dapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, void *buf, void **req); +static herr_t H5VL__native_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, const void *buf, void **req); +static herr_t H5VL__native_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_dataset_specific(void *dset, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_dataset_optional(void *dset, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_dataset_close(void *dset, hid_t dxpl_id, void **req); + +/* File callbacks */ +static void *H5VL__native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); +static void *H5VL__native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_file_optional(void *file, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_file_close(void *file, hid_t dxpl_id, void **req); + +/* Group callbacks */ +static void *H5VL__native_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req); +static void *H5VL__native_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_group_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_group_close(void *grp, hid_t dxpl_id, void **req); + +/* Link callbacks */ +static herr_t H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, + const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, + void *dst_obj, const H5VL_loc_params_t *loc_params2, + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, + void *dst_obj, const H5VL_loc_params_t *loc_params2, + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); + +/* Object callbacks */ +static void *H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_type_t *opened_type, hid_t dxpl_id, void **req); +static herr_t H5VL__native_object_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, const char *src_name, + void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_object_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments); + +/* Datatype callbacks */ +static void *H5VL__native_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req); +static void *H5VL__native_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__native_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req); + +/* Native VOL connector class struct */ +static 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 */ + (size_t)0, /* info size */ + NULL, /* info copy */ + NULL, /* info compare */ + NULL, /* info free */ + NULL, /* info to str */ + NULL, /* str to info */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_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 */ + }, + { /* request_cls */ + NULL, /* wait */ + NULL, /* notify */ + NULL, /* cancel */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* free */ + }, + 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(NULL == H5I_object_verify(H5VL_NATIVE_ID_g, H5I_VOL)) + if((H5VL_NATIVE_ID_g = H5VL_register_connector((const H5VL_class_t *)&H5VL_native_cls_g, TRUE, H5P_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_attr_create + * + * Purpose: Creates an attribute on an object. + * + * Return: Success: Pointer to attribute object + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t acpl_id, hid_t H5_ATTR_UNUSED aapl_id, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + H5G_loc_t loc; /* Object location */ + H5G_loc_t obj_loc; /* Location used to open group */ + hbool_t loc_found = FALSE; + H5P_genplist_t *plist; /* Property list pointer */ + hid_t type_id, space_id; + H5T_t *type, *dt; /* Datatype to use for attribute */ + H5S_t *space; /* Dataspace to use for attribute */ + H5A_t *attr = NULL; + void *ret_value = NULL; + + FUNC_ENTER_STATIC + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(acpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") + + /* get creation properties */ + if(H5P_get(plist, H5VL_PROP_ATTR_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id") + if(H5P_get(plist, H5VL_PROP_ATTR_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id") + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, NULL, "no write intent on file") + + if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype") + /* If this is a named datatype, get the connector's pointer to the datatype */ + type = H5T_get_actual_type(dt); + + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data space") + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { + /* H5Acreate */ + /* Go do the real work for attaching the attribute to the dataset */ + if(NULL == (attr = H5A__create(&loc, attr_name, type, space, acpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to create attribute") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { + /* H5Acreate_by_name */ + if(NULL == (attr = H5A__create_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name, type, space, acpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to create attribute") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "unknown attribute create parameters") + + ret_value = (void *)attr; + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_attr_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_attr_open + * + * Purpose: Opens an attr inside a native H5 file. + * + * Return: Success: Pointer to attribute object + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t H5_ATTR_UNUSED aapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5G_loc_t loc; /* Object location */ + H5A_t *attr = NULL; /* Attribute opened */ + void *ret_value; + + FUNC_ENTER_STATIC + + /* check arguments */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { + /* H5Aopen */ + /* Open the attribute */ + if(NULL == (attr = H5A__open(&loc, attr_name))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open attribute: '%s'", attr_name) + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { + /* H5Aopen_by_name */ + /* Open the attribute on the object header */ + if(NULL == (attr = H5A__open_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute") + } /* end else-if */ + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { + /* H5Aopen_by_idx */ + /* Open the attribute in the object header */ + if(NULL == (attr = H5A__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open attribute") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "unknown attribute open parameters") + + ret_value = (void *)attr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_attr_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_attr_read + * + * Purpose: Reads data from attribute. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5T_t *mem_type; /* Memory datatype */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_STATIC + + if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + + /* Go write the actual data to the attribute */ + if((ret_value = H5A__read((H5A_t*)attr, mem_type, buf)) < 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 data to attribute. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_attr_write(void *attr, hid_t dtype_id, const void *buf, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5T_t *mem_type; /* Memory datatype */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_STATIC + + if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + + /* Go write the actual data to the attribute */ + if((ret_value = H5A__write((H5A_t*)attr, mem_type, buf)) < 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 information about an attribute + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(get_type) { + /* H5Aget_space */ + case H5VL_ATTR_GET_SPACE: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + H5A_t *attr = (H5A_t *)obj; + + if((*ret_id = H5A_get_space(attr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of attribute") + break; + } + + /* H5Aget_type */ + case H5VL_ATTR_GET_TYPE: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + H5A_t *attr = (H5A_t *)obj; + + if((*ret_id = H5A__get_type(attr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of attribute") + break; + } + + /* H5Aget_create_plist */ + case H5VL_ATTR_GET_ACPL: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + H5A_t *attr = (H5A_t *)obj; + + if((*ret_id = H5A__get_create_plist(attr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for attr") + + break; + } + + /* H5Aget_name */ + case H5VL_ATTR_GET_NAME: + { + const H5VL_loc_params_t *loc_params = va_arg(arguments, const H5VL_loc_params_t *); + size_t buf_size = va_arg(arguments, size_t); + char *buf = va_arg(arguments, char *); + ssize_t *ret_val = va_arg(arguments, ssize_t *); + H5A_t *attr = NULL; + + if(H5VL_OBJECT_BY_SELF == loc_params->type) { + attr = (H5A_t *)obj; + /* Call private function in turn */ + if(0 > (*ret_val = H5A__get_name(attr, buf_size, buf))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name") + } + else if(H5VL_OBJECT_BY_IDX == loc_params->type) { + H5G_loc_t loc; + + /* check arguments */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Open the attribute on the object header */ + if(NULL == (attr = H5A__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + + /* Get the length of the name */ + *ret_val = (ssize_t)HDstrlen(attr->shared->name); + + /* Copy the name into the user's buffer, if given */ + if(buf) { + HDstrncpy(buf, attr->shared->name, MIN((size_t)(*ret_val + 1), buf_size)); + if((size_t)(*ret_val) >= buf_size) + buf[buf_size - 1]='\0'; + } /* end if */ + + /* Release resources */ + if(attr && H5A__close(attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + } + else + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get name of attr") + + break; + } + + /* H5Aget_info */ + case H5VL_ATTR_GET_INFO: + { + const H5VL_loc_params_t *loc_params = va_arg(arguments, const H5VL_loc_params_t *); + H5A_info_t *ainfo = va_arg(arguments, H5A_info_t *); + H5A_t *attr = NULL; + + if(H5VL_OBJECT_BY_SELF == loc_params->type) { + attr = (H5A_t *)obj; + if(H5A__get_info(attr, ainfo) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get attribute info") + } + else if(H5VL_OBJECT_BY_NAME == loc_params->type) { + char *attr_name = va_arg(arguments, char *); + H5G_loc_t loc; + + /* check arguments */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Open the attribute on the object header */ + if(NULL == (attr = H5A__open_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + + /* Get the attribute information */ + if(H5A__get_info(attr, ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") + + /* Release resources */ + if(attr && H5A__close(attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + } + else if(H5VL_OBJECT_BY_IDX == loc_params->type) { + H5G_loc_t loc; + + /* check arguments */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Open the attribute on the object header */ + if(NULL == (attr = H5A__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + + /* Get the attribute information */ + if(H5A__get_info(attr, ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") + + /* Release resources */ + if(attr && H5A__close(attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + } + else + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get name of attr") + + break; + } + + case H5VL_ATTR_GET_STORAGE_SIZE: + { + hsize_t *ret = va_arg(arguments, hsize_t *); + H5A_t *attr = (H5A_t *)obj; + + /* Set return value */ + *ret = attr->shared->data_size; + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from attr") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_attr_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_attr_specific + * + * Purpose: Specific operation on attribute + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * August, 2014 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_t specific_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Get location for passed-in object */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + switch(specific_type) { + case H5VL_ATTR_DELETE: + { + char *attr_name = va_arg(arguments, char *); + + if(H5VL_OBJECT_BY_SELF == loc_params->type) { + /* H5Adelete */ + /* Delete the attribute from the location */ + if(H5O__attr_remove(loc.oloc, attr_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } /* end if */ + else if(H5VL_OBJECT_BY_NAME == loc_params->type) { + /* H5Adelete_by_name */ + /* Delete the attribute */ + if(H5A__delete_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } /* end else-if */ + else if(H5VL_OBJECT_BY_IDX == loc_params->type) { + /* H5Adelete_by_idx */ + /* Delete the attribute from the location */ + if(H5A__delete_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute remove parameters") + break; + } + + case H5VL_ATTR_EXISTS: + { + const char *attr_name = va_arg(arguments, const char *); + htri_t *ret = va_arg(arguments, htri_t *); + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aexists */ + /* Check if the attribute exists */ + if((*ret = H5O__attr_exists(loc.oloc, attr_name)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aexists_by_name */ + /* Check if the attribute exists */ + if((*ret = H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, attr_name)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown parameters") + break; + } + + case H5VL_ATTR_ITER: + { + 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 *idx = va_arg(arguments, hsize_t *); + H5A_operator2_t op = va_arg(arguments, H5A_operator2_t); + void *op_data = va_arg(arguments, void *); + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aiterate2 */ + /* Iterate over attributes */ + if((ret_value = H5A__iterate(&loc, ".", idx_type, order, idx, op, op_data)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error iterating over attributes") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aiterate_by_name */ + /* Iterate over attributes by name */ + if((ret_value = H5A__iterate(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, idx, op, op_data)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "attribute iteration failed"); + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown parameters") + break; + } + + /* H5Arename/rename_by_name */ + case H5VL_ATTR_RENAME: + { + const char *old_name = va_arg(arguments, const char *); + const char *new_name = va_arg(arguments, const char *); + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Arename */ + /* Call attribute rename routine */ + if(H5O__attr_rename(loc.oloc, old_name, new_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Arename_by_name */ + /* Call attribute rename routine */ + if(H5A__rename_by_name(loc, loc_params->loc_data.loc_by_name.name, old_name, new_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute rename parameters") + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_attr_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_attr_optional + * + * Purpose: Perform a connector-specific operation on a native attribute + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_attr_optional(void H5_ATTR_UNUSED *obj, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5VL_attr_optional_t optional_type; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + optional_type = va_arg(arguments, H5VL_attr_optional_t); + switch(optional_type) { +#ifndef H5_NO_DEPRECATED_SYMBOLS + case H5VL_ATTR_ITERATE_OLD: + { + hid_t loc_id = va_arg(arguments, hid_t); + unsigned *attr_num = va_arg(arguments, unsigned *); + H5A_operator1_t op = va_arg(arguments, H5A_operator1_t); + void *op_data = va_arg(arguments, void *); + + /* Call the actual iteration routine */ + if((ret_value = H5A__iterate_old(loc_id, attr_num, op, op_data)) < 0) + HERROR(H5E_VOL, H5E_BADITER, "error iterating over attributes"); + + break; + } +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid optional operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_attr_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_attr_close + * + * Purpose: Closes an attribute. + * + * Return: Success: 0 + * Failure: -1, attr not closed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_attr_close(void *attr, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(H5A__close((H5A_t*)attr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't close attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_attr_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_dataset_create + * + * Purpose: Creates a dataset in a native HDF5 file + * + * Return: Success: Pointer to a dataset struct + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, + const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5G_loc_t loc; /* Object location to insert dataset into */ + hid_t type_id = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + hid_t lcpl_id = H5I_INVALID_HID; + H5D_t *dset = NULL; /* New dataset's info */ + const H5S_t *space; /* Dataspace for dataset */ + void *ret_value; + + FUNC_ENTER_STATIC + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") + + /* Get creation properties */ + if(H5P_get(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id") + if(H5P_get(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id") + if(H5P_get(plist, H5VL_PROP_DSET_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id") + + /* Check arguments */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + if(H5I_DATATYPE != H5I_get_type(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype ID") + if(NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a dataspace ID") + + /* H5Dcreate_anon */ + if(NULL == name) { + /* build and open the new dataset */ + if(NULL == (dset = H5D__create(loc.oloc->file, type_id, space, dcpl_id, dapl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset") + } /* end if */ + /* 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))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset") + } /* end else */ + + ret_value = (void *)dset; + +done: + if(NULL == name) { + /* Release the dataset's object header, if it was created */ + if(dset) { + H5O_loc_t *oloc; /* Object location for dataset */ + + /* Get the new dataset's object location */ + if(NULL == (oloc = H5D_oloc(dset))) + HDONE_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to get object location of dataset") + + /* Decrement refcount on dataset's object header in memory */ + if(H5O_dec_rc_by_loc(oloc) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object") + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_dataset_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_dataset_open + * + * Purpose: Opens a dataset in a native HDF5 file. + * + * Return: Success: Pointer to a dataset struct + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, + hid_t dapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5D_t *dset = NULL; + H5G_loc_t loc; /* Object location of group */ + void *ret_value = NULL; + + FUNC_ENTER_STATIC + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* Open the dataset */ + if(NULL == (dset = H5D__open_name(&loc, name, dapl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "unable to open dataset") + + ret_value = (void *)dset; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_dataset_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_dataset_read + * + * Purpose: Reads raw data from a dataset into a buffer. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t H5_ATTR_UNUSED dxpl_id, void *buf, + void H5_ATTR_UNUSED **req) +{ + H5D_t *dset = (H5D_t *)obj; + const H5S_t *mem_space = NULL; + const H5S_t *file_space = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if(NULL == dset->oloc.file) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file") + + /* Get validated dataspace pointers */ + if(H5S_get_validated_dataspace(mem_space_id, &mem_space) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from mem_space_id") + if(H5S_get_validated_dataspace(file_space_id, &file_space) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from file_space_id") + + /* Read raw data */ + if(H5D__read(dset, mem_type_id, mem_space, file_space, 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: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t H5_ATTR_UNUSED dxpl_id, const void *buf, + void H5_ATTR_UNUSED **req) +{ + H5D_t *dset = (H5D_t *)obj; + const H5S_t *mem_space = NULL; + const H5S_t *file_space = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* check arguments */ + if(NULL == dset->oloc.file) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file") + + /* Get validated dataspace pointers */ + if(H5S_get_validated_dataspace(mem_space_id, &mem_space) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from mem_space_id") + if(H5S_get_validated_dataspace(file_space_id, &file_space) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from file_space_id") + + /* Write the data */ + if(H5D__write(dset, mem_type_id, mem_space, file_space, 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_get + * + * Purpose: Gets certain information about a dataset + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_dataset_get(void *obj, H5VL_dataset_get_t get_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5D_t *dset = (H5D_t *)obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(get_type) { + /* H5Dget_space */ + case H5VL_DATASET_GET_SPACE: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + + if((*ret_id = H5D__get_space(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of dataset") + + break; + } + + /* H5Dget_space_statuc */ + case H5VL_DATASET_GET_SPACE_STATUS: + { + H5D_space_status_t *allocation = va_arg(arguments, H5D_space_status_t *); + + /* Read data space address and return */ + if(H5D__get_space_status(dset, allocation) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get space status") + + break; + } + + /* H5Dget_type */ + case H5VL_DATASET_GET_TYPE: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + + if((*ret_id = H5D__get_type(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of dataset") + + break; + } + + /* H5Dget_create_plist */ + case H5VL_DATASET_GET_DCPL: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + + if((*ret_id = H5D_get_create_plist(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for dataset") + + break; + } + + /* H5Dget_access_plist */ + case H5VL_DATASET_GET_DAPL: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + + if((*ret_id = H5D_get_access_plist(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get access property list for dataset") + + break; + } + + /* H5Dget_storage_size */ + case H5VL_DATASET_GET_STORAGE_SIZE: + { + hsize_t *ret = va_arg(arguments, hsize_t *); + + /* Set return value */ + if(H5D__get_storage_size(dset, ret) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get size of dataset's storage") + break; + } + + /* H5Dget_offset */ + case H5VL_DATASET_GET_OFFSET: + { + haddr_t *ret = va_arg(arguments, haddr_t *); + + /* Set return value */ + *ret = H5D__get_offset(dset); + if(!H5F_addr_defined(*ret)) + *ret = HADDR_UNDEF; + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from dataset") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_dataset_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_dataset_specific + * + * Purpose: Specific operation on dataset + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5D_t *dset = (H5D_t *)obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(specific_type) { + /* H5Dspecific_space */ + case H5VL_DATASET_SET_EXTENT: + { + const hsize_t *size = va_arg(arguments, const hsize_t *); + + if(H5D__set_extent(dset, size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset") + break; + } + + case H5VL_DATASET_FLUSH: + { + hid_t dset_id = va_arg(arguments, hid_t); + + /* Flush the dataset */ + if(H5D__flush(dset, dset_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush dataset") + + break; + } + + case H5VL_DATASET_REFRESH: + { + hid_t dset_id = va_arg(arguments, hid_t); + + /* Refresh the dataset */ + if((H5D__refresh(dset_id, dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to refresh dataset") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_dataset_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_dataset_optional + * + * Purpose: Perform a connector-specific operation on a native dataset + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_dataset_optional(void *obj, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5D_t *dset = NULL; /* Dataset */ + H5VL_dataset_optional_t optional_type = va_arg(arguments, H5VL_dataset_optional_t); + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(optional_type) { + case H5VL_DATASET_FORMAT_CONVERT: + { + dset = (H5D_t *)obj; + + switch(dset->shared->layout.type) { + case H5D_CHUNKED: + /* Convert the chunk indexing type to version 1 B-tree if not */ + if(dset->shared->layout.u.chunk.idx_type != H5D_CHUNK_IDX_BTREE) + if((H5D__format_convert(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to downgrade chunk indexing type for dataset") + break; + + case H5D_CONTIGUOUS: + case H5D_COMPACT: + /* Downgrade the layout version to 3 if greater than 3 */ + if(dset->shared->layout.version > H5O_LAYOUT_VERSION_DEFAULT) + if((H5D__format_convert(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to downgrade layout version for dataset") + break; + + case H5D_VIRTUAL: + /* Nothing to do even though layout is version 4 */ + break; + + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset layout type") + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown dataset layout type") + } /* end switch */ + + break; + } + + case H5VL_DATASET_GET_CHUNK_INDEX_TYPE: + { + H5D_chunk_index_t *idx_type = va_arg(arguments, H5D_chunk_index_t *); + + dset = (H5D_t *)obj; + + /* Make sure the dataset is chunked */ + if(H5D_CHUNKED != dset->shared->layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + + /* Get the chunk indexing type */ + *idx_type = dset->shared->layout.u.chunk.idx_type; + + break; + } + + case H5VL_DATASET_GET_CHUNK_STORAGE_SIZE: + { + hsize_t *offset = va_arg(arguments, hsize_t *); + hsize_t *chunk_nbytes = va_arg(arguments, hsize_t *); + + dset = (H5D_t *)obj; + + /* Make sure the dataset is chunked */ + if(H5D_CHUNKED != dset->shared->layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + + /* Call private function */ + if(H5D__get_chunk_storage_size(dset, offset, chunk_nbytes) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get storage size of chunk") + + break; + } + + case H5VL_DATASET_CHUNK_READ: + { + const hsize_t *offset = va_arg(arguments, hsize_t *); + uint32_t *filters = va_arg(arguments, uint32_t *); + void *buf = va_arg(arguments, void *); + hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ + + dset = (H5D_t *)obj; + + /* Check arguments */ + if(NULL == dset->oloc.file) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file") + if(H5D_CHUNKED != dset->shared->layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + + /* Copy the user's offset array so we can be sure it's terminated properly. + * (we don't want to mess with the user's buffer). + */ + if(H5D__get_offset_copy(dset, offset, offset_copy) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "failure to copy offset array") + + /* Read the raw chunk */ + if(H5D__chunk_direct_read(dset, offset_copy, filters, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") + + break; + } + + case H5VL_DATASET_CHUNK_WRITE: + { + uint32_t filters = va_arg(arguments, uint32_t); + const hsize_t *offset = va_arg(arguments, const hsize_t *); + uint32_t data_size_32 = va_arg(arguments, uint32_t); + const void *buf = va_arg(arguments, const void *); + hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ + + dset = (H5D_t *)obj; + + /* Check arguments */ + if(NULL == dset->oloc.file) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file") + if(H5D_CHUNKED != dset->shared->layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + + /* Copy the user's offset array so we can be sure it's terminated properly. + * (we don't want to mess with the user's buffer). + */ + if(H5D__get_offset_copy(dset, offset, offset_copy) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "failure to copy offset array") + + /* Write chunk */ + if(H5D__chunk_direct_write(dset, filters, offset_copy, data_size_32, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write unprocessed chunk data") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid optional operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_dataset_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_dataset_close + * + * Purpose: Closes a dataset. + * + * Return: Success: SUCCEED + * Failure: FAIL (dataset will not be closed) + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_dataset_close(void *dset, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(H5D_close((H5D_t*)dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't close dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_dataset_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_file_create + * + * Purpose: Creates a file as a native HDF5 file. + * + * Return: Success: A pointer to an H5F_t file struct + * + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5F_t *new_file = NULL; + void *ret_value = NULL; + + FUNC_ENTER_STATIC + + /* 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))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file") + new_file->id_exists = TRUE; + + ret_value = (void *)new_file; + +done: + if(NULL == ret_value && new_file) + if(H5F__close(new_file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_file_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_file_open + * + * Purpose: Opens a file as a native HDF5 file. + * + * Return: Success: A pointer to an H5F_t file struct + * + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_file_open(const char *name, unsigned flags, hid_t fapl_id, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5F_t *new_file = NULL; + void *ret_value = NULL; + + FUNC_ENTER_STATIC + + /* Open the file */ + if(NULL == (new_file = H5F_open(name, flags, H5P_FILE_CREATE_DEFAULT, fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") + new_file->id_exists = TRUE; + + ret_value = (void *)new_file; + +done: + if(NULL == ret_value && new_file && H5F_try_close(new_file, NULL) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_file_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_file_get + * + * Purpose: Get info about a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5F_t *f = NULL; /* File struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(get_type) { + /* H5Fget_access_plist */ + case H5VL_FILE_GET_FAPL: + { + H5P_genplist_t *new_plist; /* New property list */ + hid_t *plist_id = va_arg(arguments, hid_t *); + + f = (H5F_t *)obj; + + /* Retrieve the file's access property list */ + if((*plist_id = H5F_get_access_plist(f, TRUE)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list") + + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + break; + } + + /* H5Fget_create_plist */ + case H5VL_FILE_GET_FCPL: + { + H5P_genplist_t *plist; /* Property list */ + hid_t *plist_id = va_arg(arguments, hid_t *); + + f = (H5F_t *)obj; + if(NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Create the property list object to return */ + if((*plist_id = H5P_copy_plist(plist, TRUE)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy file creation properties") + + break; + } + + /* H5Fget_obj_count */ + case H5VL_FILE_GET_OBJ_COUNT: + { + unsigned types = va_arg(arguments, unsigned); + ssize_t *ret = va_arg(arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + + /* H5Fget_obj_ids */ + case H5VL_FILE_GET_OBJ_IDS: + { + unsigned types = va_arg(arguments, unsigned); + size_t max_objs = va_arg(arguments, size_t); + hid_t *oid_list = va_arg(arguments, hid_t *); + ssize_t *ret = va_arg(arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + + /* H5Fget_intent */ + case H5VL_FILE_GET_INTENT: + { + unsigned *intent_flags = va_arg(arguments, unsigned *); + + f = (H5F_t *)obj; + + /* HDF5 uses some flags internally that users don't know about. + * Simplify things for them so that they only get either H5F_ACC_RDWR + * or H5F_ACC_RDONLY and any SWMR flags. + */ + if(H5F_INTENT(f) & H5F_ACC_RDWR) { + *intent_flags = H5F_ACC_RDWR; + + /* Check for SWMR write access on the file */ + if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) + *intent_flags |= H5F_ACC_SWMR_WRITE; + } /* end if */ + else { + *intent_flags = H5F_ACC_RDONLY; + + /* Check for SWMR read access on the file */ + if(H5F_INTENT(f) & H5F_ACC_SWMR_READ) + *intent_flags |= H5F_ACC_SWMR_READ; + } /* end else */ + + break; + } + + /* H5Fget_name */ + case H5VL_FILE_GET_NAME: + { + H5I_type_t type = va_arg(arguments, H5I_type_t); + size_t size = va_arg(arguments, size_t); + char *name = va_arg(arguments, char *); + ssize_t *ret = va_arg(arguments, ssize_t *); + size_t len; + + if(NULL == (f = H5F__get_file(obj, type))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + len = HDstrlen(H5F_OPEN_NAME(f)); + + if(name) { + HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size)); + if(len >= size) + name[size-1]='\0'; + } /* end if */ + + /* Set the return value for the API call */ + *ret = (ssize_t)len; + break; + } + + case H5VL_FILE_GET_MIN_DSET_OHDR_FLAG: + { + hbool_t *minimize = va_arg(arguments, hbool_t*); + f = (H5F_t*)obj; + if (NULL == f) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + *minimize = H5F_MIN_DSET_OHDR(f); + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_file_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_file_specific + * + * Purpose: Specific operation on file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(specific_type) { + /* H5Fflush */ + case H5VL_FILE_FLUSH: + { + H5I_type_t type = va_arg(arguments, H5I_type_t); + H5F_scope_t scope = va_arg(arguments, H5F_scope_t); + H5F_t *f = NULL; /* File to flush */ + + /* Get the file for the object */ + if(NULL == (f = H5F__get_file(obj, type))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* 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) < 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) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") + } /* end else */ + } /* end if */ + break; + } + + /* H5Freopen */ + case H5VL_FILE_REOPEN: + { + void **ret = va_arg(arguments, void **); + H5F_t *new_file = NULL; + + /* Reopen the file through the VOL connector */ + if(NULL == (new_file = H5F__reopen((H5F_t *)obj))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") + new_file->id_exists = TRUE; + + *ret = (void *)new_file; + break; + } + + /* H5Fmount */ + case H5VL_FILE_MOUNT: + { + H5I_type_t type = va_arg(arguments, H5I_type_t); + const char *name = va_arg(arguments, const char *); + H5F_t *child = va_arg(arguments, H5F_t *); + hid_t plist_id = va_arg(arguments, hid_t); + H5G_loc_t loc; + + if(H5G_loc_real(obj, type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Do the mount */ + if(H5F__mount(&loc, name, child, plist_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") + + break; + } + + /* H5Funmount */ + case H5VL_FILE_UNMOUNT: + { + H5I_type_t type = va_arg(arguments, H5I_type_t); + const char *name = va_arg(arguments, const char *); + H5G_loc_t loc; + + if(H5G_loc_real(obj, type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Unmount */ + if(H5F__unmount(&loc, name) < 0) + HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") + + break; + } + + /* H5Fis_accessible */ + case H5VL_FILE_IS_ACCESSIBLE: + { + hid_t fapl_id = va_arg(arguments, hid_t); + const char *name = va_arg(arguments, const char *); + htri_t *ret = va_arg(arguments, htri_t *); + + /* Call private routine */ + if((*ret = H5F__is_hdf5(name, fapl_id)) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "error in HDF5 file check") + break; + } + + /* H5Fcreate / H5Fopen */ + case H5VL_FILE_CACHE_VOL_CONN: + { + hid_t vol_id = va_arg(arguments, hid_t); + void *vol_info = va_arg(arguments, void *); + + /* Call private routine */ + if(H5F__set_vol_conn((H5F_t *)obj, vol_id, vol_info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cache VOL connector ID & info failed") + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_file_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_file_optional + * + * Purpose: Perform a connector-specific operation on a native file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_file_optional(void *obj, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5F_t *f = NULL; /* File */ + H5VL_file_optional_t optional_type = va_arg(arguments, H5VL_file_optional_t); + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + f = (H5F_t *)obj; + switch(optional_type) { + /* H5Fget_filesize */ + case H5VL_FILE_GET_SIZE: + { + haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */ + haddr_t base_addr; /* Base address for the file */ + hsize_t *size = va_arg(arguments, hsize_t *); + + /* Go get the actual file size */ + if(H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") + + base_addr = H5FD_get_base_addr(f->shared->lf); + + if(size) + *size = (hsize_t)(max_eof_eoa + base_addr); /* Convert relative base address for file to absolute address */ + + break; + } + + /* H5Fget_file_image */ + case H5VL_FILE_GET_FILE_IMAGE: + { + void *buf_ptr = va_arg(arguments, void *); + ssize_t *ret = va_arg(arguments, ssize_t *); + size_t buf_len = va_arg(arguments, size_t ); + + /* Do the actual work */ + if((*ret = H5F__get_file_image(f, buf_ptr, buf_len)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get file image failed") + break; + } + + /* H5Fget_freespace */ + case H5VL_FILE_GET_FREE_SPACE: + { + hsize_t tot_space; /* Amount of free space in the file */ + hssize_t *ret = va_arg(arguments, hssize_t *); + + /* Go get the actual amount of free space in the file */ + if(H5MF_get_freespace(f, &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, type, nsects, sect_info)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + break; + } + + /* H5Fget_info2 */ + case H5VL_FILE_GET_INFO: + { + H5I_type_t type = va_arg(arguments, H5I_type_t); + H5F_info2_t *finfo = va_arg(arguments, H5F_info2_t *); + + /* Get the file struct. This call is careful to not return the file pointer + * for the top file in a mount hierarchy. + */ + if(NULL == (f = H5F__get_file(obj, type))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get a file struct") + + /* Get the file info */ + if(H5F__get_info(f, finfo) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") + + 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 *); + uint32_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; + } + + /* H5Fget_vfd_handle */ + case H5VL_FILE_GET_VFD_HANDLE: + { + void **file_handle = va_arg(arguments, void **); + hid_t fapl_id = va_arg(arguments, hid_t); + + /* Retrieve the VFD handle for the file */ + if(H5F_get_vfd_handle(f, fapl_id, file_handle) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle") + break; + } + + /* H5Iget_file_id */ + case H5VL_FILE_GET_FILE_ID: + { + H5I_type_t type = va_arg(arguments, H5I_type_t); + hid_t *file_id = va_arg(arguments, hid_t *); + + if(NULL == (f = H5F__get_file(obj, type))) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a file or file object") + if((*file_id = H5F__get_file_id(f)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file ID") + break; + } + + /* H5Fclear_elink_file_cache */ + case H5VL_FILE_CLEAR_ELINK_CACHE: + { + /* Release the EFC */ + if(f->shared->efc) + if(H5F__efc_release(f->shared->efc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + break; + } + + /* H5Freset_mdc_hit_rate_stats */ + case H5VL_FILE_RESET_MDC_HIT_RATE: + { + /* Reset the hit rate statistic */ + if(H5AC_reset_cache_hit_rate_stats(f->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't reset cache hit rate") + break; + } + + case H5VL_FILE_SET_MDC_CONFIG: + { + H5AC_cache_config_t *config_ptr = va_arg(arguments, H5AC_cache_config_t *); + + /* set the resize configuration */ + if(H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "H5AC_set_cache_auto_resize_config() failed") + break; + } + + case H5VL_FILE_GET_METADATA_READ_RETRY_INFO: + { + H5F_retry_info_t *info = va_arg(arguments, H5F_retry_info_t *); + + if(H5F_get_metadata_read_retry_info(f, info) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't get metadata read retry info") + + break; + } + + case H5VL_FILE_START_SWMR_WRITE: + { + if(H5F__start_swmr_write(f) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't start SWMR write") + + break; + } + + case H5VL_FILE_START_MDC_LOGGING: + { + /* Call mdc logging function */ + if(H5C_start_logging(f->shared->cache) < 0) + HGOTO_ERROR(H5E_FILE, H5E_LOGFAIL, FAIL, "unable to start mdc logging") + + break; + } + + case H5VL_FILE_STOP_MDC_LOGGING: + { + /* Call mdc logging function */ + if(H5C_stop_logging(f->shared->cache) < 0) + HGOTO_ERROR(H5E_FILE, H5E_LOGFAIL, FAIL, "unable to stop mdc logging") + + break; + } + + case H5VL_FILE_GET_MDC_LOGGING_STATUS: + { + hbool_t *is_enabled = va_arg(arguments, hbool_t *); + hbool_t *is_currently_logging = va_arg(arguments, hbool_t *); + + /* Call mdc logging function */ + if(H5C_get_logging_status(f->shared->cache, is_enabled, is_currently_logging) < 0) + HGOTO_ERROR(H5E_FILE, H5E_LOGFAIL, FAIL, "unable to get logging status") + + break; + } + + case H5VL_FILE_FORMAT_CONVERT: + { + /* Convert the format */ + if(H5F__format_convert(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "can't convert file format") + + break; + } + + case H5VL_FILE_RESET_PAGE_BUFFERING_STATS: + { + /* Sanity check */ + if(NULL == f->shared->page_buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file") + + /* Reset the statistics */ + if (H5PB_reset_stats(f->shared->page_buf) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't reset stats for page buffering") + + break; + } + + case H5VL_FILE_GET_PAGE_BUFFERING_STATS: + { + unsigned *accesses = va_arg(arguments, unsigned *); + unsigned *hits = va_arg(arguments, unsigned *); + unsigned *misses = va_arg(arguments, unsigned *); + unsigned *evictions = va_arg(arguments, unsigned *); + unsigned *bypasses = va_arg(arguments, unsigned *); + + /* Sanity check */ + if(NULL == f->shared->page_buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file") + + /* Get the statistics */ + if(H5PB_get_stats(f->shared->page_buf, accesses, hits, misses, evictions, bypasses) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering") + + break; + } + + case H5VL_FILE_GET_MDC_IMAGE_INFO: + { + haddr_t *image_addr = va_arg(arguments, haddr_t *); + hsize_t *image_len = va_arg(arguments, hsize_t *); + + /* Go get the address and size of the cache image */ + if(H5AC_get_mdc_image_info(f->shared->cache, image_addr, image_len) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info") + + break; + } + + case H5VL_FILE_GET_EOA: + { + haddr_t *eoa = va_arg(arguments, haddr_t *); + haddr_t rel_eoa; /* Relative address of EOA */ + + /* Sanity check */ + HDassert(eoa); + + /* This routine will work only for drivers with this feature enabled.*/ + /* We might introduce a new feature flag in the future */ + if(!H5F_HAS_FEATURE(f, H5FD_FEAT_SUPPORTS_SWMR_IO)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must use a SWMR-compatible VFD for this public routine") + + /* The real work */ + if(HADDR_UNDEF == (rel_eoa = H5F_get_eoa(f, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get_eoa request failed") + + /* Set return value */ + /* (Note compensating for base address subtraction in internal routine) */ + *eoa = rel_eoa + H5F_get_base_addr(f); + + break; + } + + case H5VL_FILE_INCR_FILESIZE: + { + hsize_t increment = va_arg(arguments, hsize_t); + haddr_t max_eof_eoa; /* Maximum of the relative EOA & EOF */ + + /* This public routine will work only for drivers with this feature enabled.*/ + /* We might introduce a new feature flag in the future */ + if(!H5F_HAS_FEATURE(f, H5FD_FEAT_SUPPORTS_SWMR_IO)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must use a SWMR-compatible VFD for this public routine") + + /* Get the maximum of EOA and EOF */ + if(H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") + + /* Set EOA to the maximum value + increment */ + if(H5F__set_eoa(f, H5FD_MEM_DEFAULT, max_eof_eoa + increment) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_eoa request failed") + + break; + } + + case H5VL_FILE_SET_LIBVER_BOUNDS: + { + H5F_libver_t low = va_arg(arguments, H5F_libver_t); + H5F_libver_t high = va_arg(arguments, H5F_libver_t); + + /* Call internal set_libver_bounds function */ + if(H5F__set_libver_bounds(f, low, high) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set low/high bounds") + + break; + } + + case H5VL_FILE_SET_MIN_DSET_OHDR_FLAG: + { + int minimize = va_arg(arguments, int); /* int to satisfy va_arg */ + if (0 > H5F_set_min_dset_ohdr(f, (hbool_t)minimize)) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, + "cannot set file's dataset object header minimization flag") + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid optional operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_file_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_file_close + * + * Purpose: Closes a file. + * + * Return: SUCCEED/FAIL (the file will not be closed on failure) + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_file_close(void *file, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + int nref; + H5F_t *f = (H5F_t *)file; + hid_t file_id = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* This routine should only be called when a file ID's ref count drops to zero */ + HDassert(H5F_ID_EXISTS(f)); + + /* 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((H5F_NREFS(f) > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { + /* Get the file ID corresponding to the H5F_t struct */ + if(H5I_find_id(f, H5I_FILE, &file_id) < 0 || H5I_INVALID_HID == file_id) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "invalid atom") + + /* Get the number of references outstanding for this file ID */ + if((nref = H5I_get_ref(file_id, FALSE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") + if(nref == 1) + if(H5F__flush(f) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + } /* end if */ + + /* Close the file */ + if(H5F__close(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_file_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_group_create + * + * Purpose: Creates a group inside a native h5 file. + * + * Return: Success: Pointer to a group struct + * + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name, + hid_t gcpl_id, hid_t H5_ATTR_UNUSED gapl_id, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5G_loc_t loc; /* Location to create group */ + H5G_t *grp = NULL; /* New group created */ + hid_t lcpl_id; + void *ret_value; + + FUNC_ENTER_STATIC + + /* Get the property list structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(gcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") + + /* Get creation properties */ + if(H5P_get(plist, H5VL_PROP_GRP_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id") + + /* Set up the location */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* if name is NULL then this is from H5Gcreate_anon */ + if(name == NULL) { + H5G_obj_create_t gcrt_info; /* Information for group creation */ + + /* Set up group creation info */ + gcrt_info.gcpl_id = gcpl_id; + gcrt_info.cache_type = H5G_NOTHING_CACHED; + HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache)); + + /* Create the new group & get its ID */ + if(NULL == (grp = H5G__create(loc.oloc->file, &gcrt_info))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group") + } /* end if */ + /* 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))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group") + } /* end else */ + + ret_value = (void *)grp; + +done: + if(name == NULL) { + /* Release the group's object header, if it was created */ + if(grp) { + H5O_loc_t *oloc; /* Object location for group */ + + /* Get the new group's object location */ + if(NULL == (oloc = H5G_oloc(grp))) + HDONE_ERROR(H5E_SYM, H5E_CANTGET, NULL, "unable to get object location of group") + + /* Decrement refcount on group's object header in memory */ + if(H5O_dec_rc_by_loc(oloc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object") + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_group_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_group_open + * + * Purpose: Opens a group inside a native h5 file. + * + * Return: Success: Pointer to a group struct + * + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, + hid_t H5_ATTR_UNUSED gapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5G_loc_t loc; /* Location to open group */ + H5G_t *grp = NULL; /* New group opend */ + void *ret_value; + + FUNC_ENTER_STATIC + + /* Set up the location */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* Open the group */ + if((grp = H5G__open_name(&loc, name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open group") + + ret_value = (void *)grp; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_group_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_group_get + * + * Purpose: Get info about a group + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_group_get(void *obj, H5VL_group_get_t get_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(get_type) { + /* H5Gget_create_plist */ + case H5VL_GROUP_GET_GCPL: + { + hid_t *new_gcpl_id = va_arg(arguments, hid_t *); + H5G_t *grp = (H5G_t *)obj; + + if((*new_gcpl_id = H5G_get_create_plist(grp)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for group") + break; + } + + /* H5Gget_info */ + case H5VL_GROUP_GET_INFO: + { + const H5VL_loc_params_t *loc_params = va_arg(arguments, const H5VL_loc_params_t *); + H5G_info_t *group_info = va_arg(arguments, H5G_info_t *); + H5G_loc_t loc; + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { + /* H5Gget_info */ + + /* Retrieve the group's information */ + if(H5G__obj_info(loc.oloc, group_info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { + /* H5Gget_info_by_name */ + + /* Retrieve the group's information */ + if(H5G__get_info_by_name(&loc, loc_params->loc_data.loc_by_name.name, group_info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + } /* end else-if */ + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { + /* H5Gget_info_by_idx */ + + /* Retrieve the group's information */ + if(H5G__get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, group_info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from group") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_group_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_group_specific + * + * Purpose: Specific operations for groups + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_group_specific(void *obj, H5VL_group_specific_t specific_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5G_t *grp = (H5G_t *)obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(specific_type) { + case H5VL_GROUP_FLUSH: + { + hid_t group_id = va_arg(arguments, hid_t); + + /* Flush object's metadata to file */ + if(H5O_flush_common(&grp->oloc, group_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTFLUSH, FAIL, "unable to flush group") + + break; + } + + case H5VL_GROUP_REFRESH: + { + hid_t group_id = va_arg(arguments, hid_t); + + /* Call private function to refresh group object */ + if((H5O_refresh_metadata(group_id, grp->oloc)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to refresh group") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_group_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_group_optional + * + * Purpose: Perform a connector-specific operation on a native group + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_group_optional(void *obj, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5VL_group_optional_t optional_type; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + optional_type = va_arg(arguments, H5VL_group_optional_t); + switch(optional_type) { +#ifndef H5_NO_DEPRECATED_SYMBOLS + /* H5Giterate (deprecated) */ + case H5VL_GROUP_ITERATE_OLD: + { + const H5VL_loc_params_t *loc_params = va_arg(arguments, const H5VL_loc_params_t *); + hsize_t idx = va_arg(arguments, hsize_t); + hsize_t *last_obj = va_arg(arguments, hsize_t *); + const H5G_link_iterate_t *lnk_op = va_arg(arguments, const H5G_link_iterate_t *); + void *op_data = va_arg(arguments, void *); + H5G_loc_t grp_loc; + + /* Get the location struct for the object */ + if(H5G_loc_real(obj, loc_params->obj_type, &grp_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Call the actual iteration routine */ + if((ret_value = H5G_iterate(&grp_loc, loc_params->loc_data.loc_by_name.name, H5_INDEX_NAME, H5_ITER_INC, idx, last_obj, lnk_op, op_data)) < 0) + HERROR(H5E_VOL, H5E_BADITER, "error iterating over group's links"); + + break; + } + + /* H5Gget_objinfo (deprecated) */ + case H5VL_GROUP_GET_OBJINFO: + { + const H5VL_loc_params_t *loc_params = va_arg(arguments, const H5VL_loc_params_t *); + hbool_t follow_link = va_arg(arguments, unsigned); + H5G_stat_t *statbuf = va_arg(arguments, H5G_stat_t *); + H5G_loc_t grp_loc; + + /* Get the location struct for the object */ + if(H5G_loc_real(obj, loc_params->obj_type, &grp_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Call the actual group objinfo routine */ + if(H5G__get_objinfo(&grp_loc, loc_params->loc_data.loc_by_name.name, follow_link, statbuf) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "cannot stat object") + + break; + } +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid optional operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_group_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_group_close + * + * Purpose: Closes a group. + * + * Return: SUCCEED/FAIL (the group will not be closed on failure) + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_group_close(void *grp, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(H5G_close((H5G_t *)grp) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close group") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_group_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_link_create + * + * Purpose: Creates an hard/soft/UD/external links. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, + const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(lcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + + switch(create_type) { + case H5VL_LINK_CREATE_HARD: + { + H5G_loc_t cur_loc; + H5G_loc_t link_loc; + void *cur_obj; + H5VL_loc_params_t cur_params; + + if(H5P_get(plist, H5VL_PROP_LINK_TARGET, &cur_obj) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current location id") + if(H5P_get(plist, H5VL_PROP_LINK_TARGET_LOC_PARAMS, &cur_params) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current name") + + if(NULL != cur_obj && H5G_loc_real(cur_obj, cur_params.obj_type, &cur_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL != obj && H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* H5Lcreate_hard */ + if(H5VL_OBJECT_BY_NAME == cur_params.type) { + H5G_loc_t *cur_loc_p, *link_loc_p; + + /* Set up current & new location pointers */ + cur_loc_p = &cur_loc; + link_loc_p = &link_loc; + if(NULL == cur_obj) + cur_loc_p = link_loc_p; + else if(NULL == obj) + link_loc_p = cur_loc_p; + else if(cur_loc_p->oloc->file != link_loc_p->oloc->file) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.") + + /* Create the link */ + if((ret_value = H5L_create_hard(cur_loc_p, cur_params.loc_data.loc_by_name.name, + link_loc_p, loc_params->loc_data.loc_by_name.name, lcpl_id)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + } /* end if */ + else { /* H5Olink */ + /* Link to the object */ + if(H5L_link(&link_loc, loc_params->loc_data.loc_by_name.name, &cur_loc, lcpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create link") + } /* end else */ + break; + } + + case H5VL_LINK_CREATE_SOFT: + { + char *target_name; + H5G_loc_t link_loc; /* Group location for new link */ + + if(H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + if(H5P_get(plist, H5VL_PROP_LINK_TARGET_NAME, &target_name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for targe name") + + /* Create the link */ + if((ret_value = H5L_create_soft(target_name, &link_loc, loc_params->loc_data.loc_by_name.name, lcpl_id)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + break; + } + + case H5VL_LINK_CREATE_UD: + { + H5G_loc_t link_loc; /* Group location for new link */ + H5L_type_t link_type; + void *udata; + size_t udata_size; + + if(H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + if(H5P_get(plist, H5VL_PROP_LINK_TYPE, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for link type") + if(H5P_get(plist, H5VL_PROP_LINK_UDATA, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for udata") + if(H5P_get(plist, H5VL_PROP_LINK_UDATA_SIZE, &udata_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for udata size") + + /* Create link */ + if(H5L__create_ud(&link_loc, loc_params->loc_data.loc_by_name.name, udata, udata_size, + link_type, lcpl_id) < 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") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_link_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_link_copy + * + * Purpose: Renames an object within an HDF5 file and copies 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_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, + void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, + hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + H5G_loc_t src_loc, *src_loc_p; + H5G_loc_t dst_loc, *dst_loc_p; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(NULL != src_obj && H5G_loc_real(src_obj, loc_params1->obj_type, &src_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL != dst_obj && H5G_loc_real(dst_obj, loc_params2->obj_type, &dst_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Set up src & dst location pointers */ + src_loc_p = &src_loc; + dst_loc_p = &dst_loc; + if(NULL == src_obj) + src_loc_p = dst_loc_p; + else if(NULL == dst_obj) + dst_loc_p = src_loc_p; + + /* Copy the link */ + if(H5L_move(src_loc_p, loc_params1->loc_data.loc_by_name.name, + dst_loc_p, loc_params2->loc_data.loc_by_name.name, + TRUE, lcpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_link_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_link_move + * + * Purpose: Renames an object within an HDF5 file and moves it to a new + * group. The original name SRC is unlinked from the group graph + * and then inserted with the new name DST (which can specify a + * new path for the object) as an atomic operation. The names + * are interpreted relative to SRC_LOC_ID and + * DST_LOC_ID, which are either file IDs or group ID. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, + void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, + hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + H5G_loc_t src_loc, *src_loc_p; + H5G_loc_t dst_loc, *dst_loc_p; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(NULL != src_obj && H5G_loc_real(src_obj, loc_params1->obj_type, &src_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL != dst_obj && H5G_loc_real(dst_obj, loc_params2->obj_type, &dst_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Set up src & dst location pointers */ + src_loc_p = &src_loc; + dst_loc_p = &dst_loc; + if(NULL == src_obj) + src_loc_p = dst_loc_p; + else if(NULL == dst_obj) + dst_loc_p = src_loc_p; + + /* Move the link */ + if(H5L_move(src_loc_p, loc_params1->loc_data.loc_by_name.name, + dst_loc_p, loc_params2->loc_data.loc_by_name.name, + FALSE, lcpl_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_get + * + * Purpose: Get info about a link + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + switch(get_type) { + /* H5Lget_info/H5Lget_info_by_idx */ + case H5VL_LINK_GET_INFO: + { + H5L_info_t *linfo = va_arg(arguments, H5L_info_t *); + + /* Get the link information */ + if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_info */ + if(H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, linfo) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_info_by_idx */ + if(H5L_get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, linfo) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") + } /* end else-if */ + else + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") + break; + } + + /* H5Lget_name_by_idx */ + case H5VL_LINK_GET_NAME: + { + char *name = va_arg(arguments, char *); + size_t size = va_arg(arguments, size_t); + ssize_t *ret = va_arg(arguments, ssize_t *); + + /* Get the link name */ + if((*ret = H5L_get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, name, size)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") + + break; + } + + /* H5Lget_val/H5Lget_val_by_idx */ + case H5VL_LINK_GET_VAL: + { + void *buf = va_arg(arguments, void *); + size_t size = va_arg(arguments, size_t); + + /* Get the link information */ + if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_val */ + if(H5L_get_val(&loc, loc_params->loc_data.loc_by_name.name, buf, size) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link value") + } + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_val_by_idx */ + + if(H5L_get_val_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, buf, size) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val") + } + else + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from link") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_link_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_link_specific + * + * Purpose: Specific operation on a link + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(specific_type) { + case H5VL_LINK_EXISTS: + { + htri_t *ret = va_arg(arguments, htri_t *); + H5G_loc_t loc; + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Check for the existence of the link */ + if((*ret = H5L_exists(&loc, loc_params->loc_data.loc_by_name.name)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to specific link info") + break; + } + + case H5VL_LINK_ITER: + { + H5G_loc_t loc; + hbool_t recursive = va_arg(arguments, int); + 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 *idx_p = va_arg(arguments, hsize_t *); + H5L_iterate_t op = va_arg(arguments, H5L_iterate_t); + void *op_data = va_arg(arguments, void *); + + /* Get the location */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + /* Visit or iterate over the links */ + if(loc_params->type == H5VL_OBJECT_BY_SELF) { + if(recursive) { + /* H5Lvisit */ + if((ret_value = H5G_visit(&loc, ".", idx_type, order, op, op_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") + } /* end if */ + else { + /* H5Literate */ + if((ret_value = H5L_iterate(&loc, ".", idx_type, order, idx_p, op, op_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links") + } /* end else */ + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { + if(recursive) { + /* H5Lvisit_by_name */ + if((ret_value = H5G_visit(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, op, op_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") + } /* end if */ + else { + /* H5Literate_by_name */ + if((ret_value = H5L_iterate(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, idx_p, op, op_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links") + } /* end else */ + } /* end else-if */ + else + HGOTO_ERROR(H5E_LINK, H5E_UNSUPPORTED, FAIL, "unknown link iterate params") + + break; + } + + case H5VL_LINK_DELETE: + { + H5G_loc_t loc; + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Unlink */ + if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Ldelete */ + if(H5L_delete(&loc, loc_params->loc_data.loc_by_name.name) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Ldelete_by_idx */ + if(H5L_delete_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + } /* end else-if */ + else + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_link_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_object_open + * + * Purpose: Opens an object inside a native h5 file. + * + * Return: Success: object id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_type_t *opened_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5G_loc_t loc; + void *ret_value = NULL; + + FUNC_ENTER_STATIC + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + switch(loc_params->type) { + case H5VL_OBJECT_BY_NAME: + { + /* Open the object */ + if(NULL == (ret_value = H5O_open_name(&loc, loc_params->loc_data.loc_by_name.name, opened_type))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by name") + break; + } + + case H5VL_OBJECT_BY_IDX: + { + /* Open the object */ + if(NULL == (ret_value = H5O_open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, opened_type))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by index") + break; + } + + case H5VL_OBJECT_BY_ADDR: + { + /* Open the object */ + if(NULL == (ret_value = H5O_open_by_addr(&loc, loc_params->loc_data.loc_by_addr.addr, opened_type))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by address") + break; + } + + case H5VL_OBJECT_BY_REF: + { + hid_t temp_id = H5I_INVALID_HID; + H5F_t *file = NULL; + + /* Get the file pointer from the entry */ + file = loc.oloc->file; + + /* Create reference */ + if((temp_id = H5R__dereference(file, loc_params->loc_data.loc_by_ref.lapl_id, + loc_params->loc_data.loc_by_ref.ref_type, + loc_params->loc_data.loc_by_ref._ref)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, NULL, "unable to dereference object") + + *opened_type = H5I_get_type(temp_id); + if(NULL == (ret_value = H5I_remove(temp_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object") + break; + } + + case H5VL_OBJECT_BY_SELF: + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "unknown open parameters") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_object_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_object_copy + * + * Purpose: Copies an object inside a native h5 file. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_object_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, const char *src_name, + void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5G_loc_t src_loc; /* Source object group location */ + H5G_loc_t dst_loc; /* Destination group location */ + herr_t ret_value = FAIL; + + FUNC_ENTER_STATIC + + /* get location for objects */ + if(H5G_loc_real(src_obj, loc_params1->obj_type, &src_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(H5G_loc_real(dst_obj, loc_params2->obj_type, &dst_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Copy the object */ + if((ret_value = H5O_copy(&src_loc, src_name, &dst_loc, dst_name, ocpypl_id, lcpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_object_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_object_get + * + * Purpose: Gets certain data about an object + * + * Return: SUCCEED/FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + H5G_loc_t loc; /* Location of group */ + + FUNC_ENTER_STATIC + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + switch(get_type) { + /* H5Rget_region */ + case H5VL_REF_GET_REGION: + { + hid_t *ret = va_arg(arguments, hid_t *); + H5R_type_t H5_ATTR_UNUSED ref_type = va_arg(arguments, H5R_type_t); + void *ref = va_arg(arguments, void *); + H5S_t *space = NULL; /* Dataspace object */ + + /* Get the dataspace with the correct region selected */ + if((space = H5R__get_region(loc.oloc->file, ref)) == NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve region") + + /* Atomize */ + if((*ret = H5I_register(H5I_DATASPACE, space, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + + break; + } + + /* H5Rget_obj_type2 */ + case H5VL_REF_GET_TYPE: + { + H5O_type_t *obj_type = va_arg(arguments, H5O_type_t *); + H5R_type_t ref_type = va_arg(arguments, H5R_type_t); + void *ref = va_arg(arguments, void *); + + /* Get the object information */ + if(H5R__get_obj_type(loc.oloc->file, ref_type, ref, obj_type) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object type") + break; + } + + /* H5Rget_name */ + case H5VL_REF_GET_NAME: + { + ssize_t *ret = va_arg(arguments, ssize_t *); + char *name = va_arg(arguments, char *); + size_t size = va_arg(arguments, size_t); + H5R_type_t ref_type = va_arg(arguments, H5R_type_t); + void *ref = va_arg(arguments, void *); + + /* Get name */ + if((*ret = H5R__get_name(loc.oloc->file, ref_type, ref, name, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to determine object path") + break; + } + + /* H5Iget_name */ + case H5VL_ID_GET_NAME: + { + ssize_t *ret = va_arg(arguments, ssize_t *); + char *name = va_arg(arguments, char *); + size_t size = va_arg(arguments, size_t); + + /* Retrieve object's name */ + if((*ret = H5G_get_name(&loc, name, size, NULL)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object name") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from object") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_object_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_object_specific + * + * Purpose: Specific operation on an object + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_specific_t specific_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + switch(specific_type) { + /* H5Oincr_refcount / H5Odecr_refcount */ + case H5VL_OBJECT_CHANGE_REF_COUNT: + { + int update_ref = va_arg(arguments, int); + H5O_loc_t *oloc = loc.oloc; + + if(H5O_link(oloc, update_ref) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") + + break; + } + + /* H5Oexists_by_name */ + case H5VL_OBJECT_EXISTS: + { + htri_t *ret = va_arg(arguments, htri_t *); + + if(loc_params->type == H5VL_OBJECT_BY_NAME) { + /* Check if the object exists */ + if((*ret = H5G_loc_exists(&loc, loc_params->loc_data.loc_by_name.name)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", loc_params->loc_data.loc_by_name.name) + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object exists parameters") + break; + } + + case H5VL_OBJECT_VISIT: + { + H5_index_t idx_type = va_arg(arguments, H5_index_t); + H5_iter_order_t order = va_arg(arguments, H5_iter_order_t); + H5O_iterate_t op = va_arg(arguments, H5O_iterate_t); + void *op_data = va_arg(arguments, void *); + unsigned fields = va_arg(arguments, unsigned); + + /* Call internal object visitation routine */ + if(loc_params->type == H5VL_OBJECT_BY_SELF) { + /* H5Ovisit */ + if((ret_value = H5O__visit(&loc, ".", idx_type, order, op, op_data, fields)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { + /* H5Ovisit_by_name */ + if((ret_value = H5O__visit(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, op, op_data, fields)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object visit params"); + break; + } + + case H5VL_OBJECT_FLUSH: + { + hid_t oid = va_arg(arguments, hid_t); + + /* Flush the object's metadata */ + if(H5O_flush(loc.oloc, oid) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") + + break; + } + + case H5VL_OBJECT_REFRESH: + { + hid_t oid = va_arg(arguments, hid_t); + H5O_loc_t *oloc = loc.oloc; + + /* Refresh the metadata */ + if(H5O_refresh_metadata(oid, *oloc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") + + break; + } + + case H5VL_REF_CREATE: + { + void *ref = va_arg(arguments, void *); + const char *name = va_arg(arguments, char *); + H5R_type_t ref_type = va_arg(arguments, H5R_type_t); + hid_t space_id = va_arg(arguments, hid_t); + H5S_t *space = NULL; /* Pointer to dataspace containing region */ + + if(space_id != (-1) && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + /* Create reference */ + if(H5R__create(ref, &loc, name, ref_type, space) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create reference") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_object_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_object_optional + * + * Purpose: Perform a connector-specific operation for an objectibute + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_object_optional(void *obj, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5VL_object_optional_t optional_type = va_arg(arguments, H5VL_object_optional_t); + H5VL_loc_params_t *loc_params = va_arg(arguments, H5VL_loc_params_t *); + H5G_loc_t loc; /* Location of group */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + switch(optional_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 *); + unsigned fields = va_arg(arguments, unsigned); + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ + /* Retrieve the object's information */ + if(H5G_loc_info(&loc, ".", obj_info, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ + /* Retrieve the object's information */ + if(H5G_loc_info(&loc, loc_params->loc_data.loc_by_name.name, obj_info, fields) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end else-if */ + else if(loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location, according to the order in the index */ + if(H5G_loc_find_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, &obj_loc/*out*/) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") + + /* Retrieve the object's information */ + if(H5O_get_info(obj_loc.oloc, obj_info, fields) < 0) { + H5G_loc_free(&obj_loc); + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") + } /* end if */ + + /* Release the object location */ + if(H5G_loc_free(&obj_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location") + } /* end else-if */ + else + HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + break; + } + + /* H5Oget_comment / H5Oget_comment_by_name */ + case H5VL_OBJECT_GET_COMMENT: + { + char *comment = va_arg(arguments, char *); + size_t bufsize = va_arg(arguments, size_t); + ssize_t *ret = va_arg(arguments, ssize_t *); + + /* Retrieve the object's comment */ + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_comment */ + if((*ret = H5G_loc_get_comment(&loc, ".", comment/*out*/, bufsize)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_comment_by_name */ + if((*ret = H5G_loc_get_comment(&loc, loc_params->loc_data.loc_by_name.name, comment/*out*/, bufsize)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + break; + } + + /* H5Oset_comment */ + case H5VL_OBJECT_SET_COMMENT: + { + const char *comment = va_arg(arguments, char *); + + if(loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oset_comment */ + /* (Re)set the object's comment */ + if(H5G_loc_set_comment(&loc, ".", comment) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end if */ + else if(loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oset_comment_by_name */ + /* (Re)set the object's comment */ + if(H5G_loc_set_comment(&loc, loc_params->loc_data.loc_by_name.name, comment) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + } /* end else-if */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't perform this operation on object"); + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_object_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_datatype_commit + * + * Purpose: Commits a datatype inside a native h5 file. + * + * Return: Success: datatype id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *name, + hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t H5_ATTR_UNUSED tapl_id, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5G_loc_t loc; /* Location to commit datatype */ + H5T_t *dt; /* Datatype for ID */ + H5T_t *type = NULL; /* copy of the original type which will be committed */ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_STATIC + + /* check arguments */ + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype") + + /* Check arguments. We cannot commit an immutable type because H5Tclose() + * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing + * a named type should always succeed. + */ + if(H5T_STATE_NAMED == dt->shared->state || H5T_STATE_OPEN == dt->shared->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "datatype is already committed") + if(H5T_STATE_IMMUTABLE == dt->shared->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "datatype is immutable") + + /* Check for a "sensible" datatype to store on disk */ + if(H5T_is_sensible(dt) <= 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "datatype is not sensible") + + /* Copy the datatype - the copied one will be the type that is + * committed, and attached to original datatype above the VOL + * layer + */ + if(NULL == (type = H5T_copy(dt, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy"); + + /* Commit the datatype */ + if(NULL != name) { + /* H5Tcommit */ + if(H5T__commit_named(&loc, name, type, lcpl_id, tcpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to commit datatype") + } /* end if */ + else { + /* H5Tcommit_anon */ + if(H5T__commit_anon(loc.oloc->file, type, tcpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to commit datatype") + } /* end else */ + + ret_value = (void *)type; + +done: + if(NULL == ret_value && type) + H5T_close(type); + + 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 pointer + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__native_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, + hid_t H5_ATTR_UNUSED tapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + H5T_t *type = NULL; /* Datatype opened in file */ + H5G_loc_t loc; /* Group location of object to open */ + void *ret_value = NULL; + + FUNC_ENTER_STATIC + + if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* Open the datatype */ + if(NULL == (type = H5T__open_name(&loc, name))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open named datatype") + + type->vol_obj = NULL; + + ret_value = (void *)type; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_datatype_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_datatype_get + * + * Purpose: Get information about a datatype + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * June, 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_datatype_get(void *obj, H5VL_datatype_get_t get_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5T_t *dt = (H5T_t *)obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch (get_type) { + case H5VL_DATATYPE_GET_BINARY: + { + ssize_t *nalloc = va_arg(arguments, ssize_t *); + void *buf = va_arg(arguments, void *); + size_t size = va_arg(arguments, size_t); + + if(H5T_encode(dt, (unsigned char *)buf, &size) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't determine serialized length of datatype") + + *nalloc = (ssize_t) size; + break; + } + + /* H5Tget_create_plist */ + case H5VL_DATATYPE_GET_TCPL: + { + hid_t *ret_id = va_arg(arguments, hid_t *); + + if(H5I_INVALID_HID == (*ret_id = H5T__get_create_plist(dt))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get object creation info"); + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from datatype") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_datatype_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_datatype_specific + * + * Purpose: Specific operations for datatype + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +{ + H5T_t *dt = (H5T_t *)obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + switch(specific_type) { + case H5VL_DATATYPE_FLUSH: + { + hid_t type_id = va_arg(arguments, hid_t); + + /* To flush metadata and invoke flush callback if there is */ + if (H5O_flush_common(&dt->oloc, type_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFLUSH, FAIL, "unable to flush datatype") + + break; + } + + case H5VL_DATATYPE_REFRESH: + { + hid_t type_id = va_arg(arguments, hid_t); + + /* Call private function to refresh datatype object */ + if ((H5O_refresh_metadata(type_id, dt->oloc)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "unable to refresh datatype") + + break; + } + + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_datatype_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__native_datatype_close + * + * Purpose: Closes a datatype. + * + * Return: Success: 0 + * Failure: -1, datatype not closed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_datatype_close(void *dt, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + if(H5T_close((H5T_t*)dt) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't close datatype") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_datatype_close() */ + |