Coverage Report

Created: 2026-05-30 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5VLcallback.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*
14
 * Purpose:     The Virtual Object Layer as described in documentation.
15
 *              The purpose is to provide an abstraction on how to access the
16
 *              underlying HDF5 container, whether in a local file with
17
 *              a specific file format, or remotely on other machines, etc...
18
 */
19
20
/****************/
21
/* Module Setup */
22
/****************/
23
24
#include "H5VLmodule.h" /* This source code file is part of the H5VL module */
25
26
/***********/
27
/* Headers */
28
/***********/
29
30
#include "H5private.h"   /* Generic Functions                                */
31
#include "H5Eprivate.h"  /* Error handling                                   */
32
#include "H5ESprivate.h" /* Event Sets                                       */
33
#include "H5Fprivate.h"  /* File access                                      */
34
#include "H5Iprivate.h"  /* IDs                                              */
35
#include "H5MMprivate.h" /* Memory management                                */
36
#include "H5Pprivate.h"  /* Property lists                                   */
37
#include "H5PLprivate.h" /* Plugins                                          */
38
#include "H5Tprivate.h"  /* Datatypes                                        */
39
#include "H5VLpkg.h"     /* Virtual Object Layer                             */
40
41
/****************/
42
/* Local Macros */
43
/****************/
44
45
/******************/
46
/* Local Typedefs */
47
/******************/
48
49
/* Structure used when trying to find a
50
 * VOL connector to open a given file with.
51
 */
52
typedef struct H5VL_file_open_find_connector_t {
53
    const char         *filename;
54
    const H5VL_class_t *cls;
55
    hid_t               fapl_id;
56
} H5VL_file_open_find_connector_t;
57
58
/* Typedef for common callback form of registered optional operations */
59
typedef herr_t (*H5VL_reg_opt_oper_t)(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args,
60
                                      hid_t dxpl_id, void **req);
61
62
/********************/
63
/* Package Typedefs */
64
/********************/
65
66
/********************/
67
/* Local Prototypes */
68
/********************/
69
/* Helper routines */
70
static herr_t H5VL__common_optional_op(hid_t id, H5I_type_t id_type, H5VL_reg_opt_oper_t reg_opt_op,
71
                                       H5VL_optional_args_t *args, hid_t dxpl_id, void **req,
72
                                       H5VL_object_t **_vol_obj_ptr);
73
74
/* VOL connector callback equivalents */
75
static void  *H5VL__attr_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
76
                                const char *name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
77
                                hid_t dxpl_id, void **req);
78
static void  *H5VL__attr_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
79
                              const char *name, hid_t aapl_id, hid_t dxpl_id, void **req);
80
static herr_t H5VL__attr_read(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, void *buf, hid_t dxpl_id,
81
                              void **req);
82
static herr_t H5VL__attr_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, const void *buf,
83
                               hid_t dxpl_id, void **req);
84
static herr_t H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_args_t *args, hid_t dxpl_id,
85
                             void **req);
86
static herr_t H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
87
                                  H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req);
88
static herr_t H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args,
89
                                  hid_t dxpl_id, void **req);
90
static herr_t H5VL__attr_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req);
91
static void  *H5VL__dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
92
                                   const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id,
93
                                   hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
94
static void  *H5VL__dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
95
                                 const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
96
static herr_t H5VL__dataset_read(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
97
                                 hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, void *buf[],
98
                                 void **req);
99
static herr_t H5VL__dataset_write(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
100
                                  hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id,
101
                                  const void *buf[], void **req);
102
static herr_t H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_args_t *args,
103
                                hid_t dxpl_id, void **req);
104
static herr_t H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_args_t *args,
105
                                     hid_t dxpl_id, void **req);
106
static herr_t H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args,
107
                                     hid_t dxpl_id, void **req);
108
static herr_t H5VL__dataset_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req);
109
static void  *H5VL__datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
110
                                    const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id,
111
                                    hid_t tapl_id, hid_t dxpl_id, void **req);
112
static void  *H5VL__datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
113
                                  const char *name, hid_t tapl_id, hid_t dxpl_id, void **req);
114
static herr_t H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_args_t *args,
115
                                 hid_t dxpl_id, void **req);
116
static herr_t H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_args_t *args,
117
                                      hid_t dxpl_id, void **req);
118
static herr_t H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args,
119
                                      hid_t dxpl_id, void **req);
120
static herr_t H5VL__datatype_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req);
121
static void  *H5VL__file_create(const H5VL_class_t *cls, const char *name, unsigned flags, hid_t fcpl_id,
122
                                hid_t fapl_id, hid_t dxpl_id, void **req);
123
static void  *H5VL__file_open(const H5VL_class_t *cls, const char *name, unsigned flags, hid_t fapl_id,
124
                              hid_t dxpl_id, void **req);
125
static herr_t H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_info,
126
                                                void *op_data);
127
static herr_t H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_args_t *args, hid_t dxpl_id,
128
                             void **req);
129
static herr_t H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_args_t *args,
130
                                  hid_t dxpl_id, void **req);
131
static herr_t H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args,
132
                                  hid_t dxpl_id, void **req);
133
static herr_t H5VL__file_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req);
134
static void  *H5VL__group_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
135
                                 const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id,
136
                                 void **req);
137
static void  *H5VL__group_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
138
                               const char *name, hid_t gapl_id, hid_t dxpl_id, void **req);
139
static herr_t H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_args_t *args, hid_t dxpl_id,
140
                              void **req);
141
static herr_t H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_args_t *args,
142
                                   hid_t dxpl_id, void **req);
143
static herr_t H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args,
144
                                   hid_t dxpl_id, void **req);
145
static herr_t H5VL__group_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req);
146
static herr_t H5VL__link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params,
147
                                const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id,
148
                                void **req);
149
static herr_t H5VL__link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
150
                              const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id,
151
                              hid_t lapl_id, hid_t dxpl_id, void **req);
152
static herr_t H5VL__link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
153
                              const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id,
154
                              hid_t lapl_id, hid_t dxpl_id, void **req);
155
static herr_t H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
156
                             H5VL_link_get_args_t *args, hid_t dxpl_id, void **req);
157
static herr_t H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
158
                                  H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req);
159
static herr_t H5VL__link_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
160
                                  H5VL_optional_args_t *args, hid_t dxpl_id, void **req);
161
static void  *H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls,
162
                                H5I_type_t *opened_type, hid_t dxpl_id, void **req);
163
static herr_t H5VL__object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name,
164
                                void *dst_obj, const H5VL_loc_params_t *dst_loc_params, const char *dst_name,
165
                                const H5VL_class_t *cls, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id,
166
                                void **req);
167
static herr_t H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
168
                               H5VL_object_get_args_t *args, hid_t dxpl_id, void **req);
169
static herr_t H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
170
                                    H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req);
171
static herr_t H5VL__object_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
172
                                    H5VL_optional_args_t *args, hid_t dxpl_id, void **req);
173
static herr_t H5VL__introspect_get_conn_cls(void *obj, const H5VL_class_t *cls, H5VL_get_conn_lvl_t lvl,
174
                                            const H5VL_class_t **conn_cls);
175
static herr_t H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t subcls,
176
                                         int opt_type, uint64_t *flags);
177
static herr_t H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout,
178
                                 H5VL_request_status_t *status);
179
static herr_t H5VL__request_notify(void *req, const H5VL_class_t *cls, H5VL_request_notify_t cb, void *ctx);
180
static herr_t H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status);
181
static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_args_t *args);
182
static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_optional_args_t *args);
183
static herr_t H5VL__request_free(void *req, const H5VL_class_t *cls);
184
static herr_t H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size, void *blob_id,
185
                             void *ctx);
186
static herr_t H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id, void *buf, size_t size,
187
                             void *ctx);
188
static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id,
189
                                  H5VL_blob_specific_args_t *args);
190
static herr_t H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id,
191
                                  H5VL_optional_args_t *args);
192
static herr_t H5VL__token_cmp(void *obj, const H5VL_class_t *cls, const H5O_token_t *token1,
193
                              const H5O_token_t *token2, int *cmp_value);
194
static herr_t H5VL__token_to_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls,
195
                                 const H5O_token_t *token, char **token_str);
196
static herr_t H5VL__token_from_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls,
197
                                   const char *token_str, H5O_token_t *token);
198
static herr_t H5VL__optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id,
199
                             void **req);
200
201
/*********************/
202
/* Package Variables */
203
/*********************/
204
205
/*****************************/
206
/* Library Private Variables */
207
/*****************************/
208
209
/*******************/
210
/* Local Variables */
211
/*******************/
212
213
/*-------------------------------------------------------------------------
214
 * Function:    H5VLinitialize
215
 *
216
 * Purpose:     Calls the connector-specific callback to initialize the connector.
217
 *
218
 * Return:      Success:    Non-negative
219
 *              Failure:    Negative
220
 *
221
 *-------------------------------------------------------------------------
222
 */
223
herr_t
224
H5VLinitialize(hid_t connector_id, hid_t vipl_id)
225
0
{
226
0
    H5VL_connector_t *connector;           /* VOL connector */
227
0
    herr_t            ret_value = SUCCEED; /* Return value */
228
229
0
    FUNC_ENTER_API_NOINIT
230
231
    /* Check args */
232
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
233
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
234
235
    /* Invoke class' callback, if there is one */
236
0
    if (connector->cls->initialize) {
237
        /* Prepare & restore library for user callback */
238
0
        H5_BEFORE_USER_CB(FAIL)
239
0
            {
240
0
                ret_value = connector->cls->initialize(vipl_id);
241
0
            }
242
0
        H5_AFTER_USER_CB(FAIL)
243
0
        if (ret_value < 0)
244
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "VOL connector did not initialize");
245
0
    }
246
247
0
done:
248
0
    FUNC_LEAVE_API_NOINIT(ret_value)
249
0
} /* end H5VLinitialize() */
250
251
/*-------------------------------------------------------------------------
252
 * Function:    H5VLterminate
253
 *
254
 * Purpose:     Calls the connector-specific callback to terminate the connector.
255
 *
256
 * Return:      Success:    Non-negative
257
 *              Failure:    Negative
258
 *
259
 *-------------------------------------------------------------------------
260
 */
261
herr_t
262
H5VLterminate(hid_t connector_id)
263
0
{
264
0
    H5VL_connector_t *connector;           /* VOL connector */
265
0
    herr_t            ret_value = SUCCEED; /* Return value */
266
267
0
    FUNC_ENTER_API_NOINIT
268
269
    /* Check args */
270
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
271
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
272
273
    /* Invoke class' callback, if there is one */
274
0
    if (connector->cls->terminate) {
275
        /* Prepare & restore library for user callback */
276
0
        H5_BEFORE_USER_CB(FAIL)
277
0
            {
278
0
                ret_value = connector->cls->terminate();
279
0
            }
280
0
        H5_AFTER_USER_CB(FAIL)
281
0
        if (ret_value < 0)
282
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "VOL connector did not terminate cleanly");
283
0
    }
284
285
0
done:
286
0
    FUNC_LEAVE_API_NOINIT(ret_value)
287
0
} /* end H5VLterminate() */
288
289
/*---------------------------------------------------------------------------
290
 * Function:    H5VLget_cap_flags
291
 *
292
 * Purpose:     Retrieves the capability flag for a connector
293
 *
294
 * Return:      Success:    Non-negative
295
 *              Failure:    Negative
296
 *
297
 *---------------------------------------------------------------------------
298
 */
299
herr_t
300
H5VLget_cap_flags(hid_t connector_id, uint64_t *cap_flags /*out*/)
301
0
{
302
0
    H5VL_connector_t *connector;           /* VOL connector */
303
0
    herr_t            ret_value = SUCCEED; /* Return value */
304
305
0
    FUNC_ENTER_API_NOINIT
306
307
    /* Check args */
308
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
309
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
310
311
    /* Retrieve capability flags */
312
0
    if (cap_flags)
313
0
        *cap_flags = connector->cls->cap_flags;
314
315
0
done:
316
0
    FUNC_LEAVE_API_NOINIT(ret_value)
317
0
} /* H5VLget_cap_flags */
318
319
/*---------------------------------------------------------------------------
320
 * Function:    H5VLget_value
321
 *
322
 * Purpose:     Retrieves the 'value' for a connector
323
 *
324
 * Return:      Success:    Non-negative
325
 *              Failure:    Negative
326
 *
327
 *---------------------------------------------------------------------------
328
 */
329
herr_t
330
H5VLget_value(hid_t connector_id, H5VL_class_value_t *value /*out*/)
331
0
{
332
0
    H5VL_connector_t *connector;           /* VOL connector */
333
0
    herr_t            ret_value = SUCCEED; /* Return value */
334
335
0
    FUNC_ENTER_API_NOINIT
336
337
    /* Check args */
338
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
339
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
340
341
    /* Retrieve connector value */
342
0
    if (value)
343
0
        *value = connector->cls->value;
344
345
0
done:
346
0
    FUNC_LEAVE_API_NOINIT(ret_value)
347
0
} /* H5VLget_value */
348
349
/*-------------------------------------------------------------------------
350
 * Function:    H5VL__common_optional_op
351
 *
352
 * Purpose:     Performs an optional connector-specific operation on an object
353
 *
354
 * Return:      Success:    Non-negative
355
 *              Failure:    Negative
356
 *
357
 *-------------------------------------------------------------------------
358
 */
359
static herr_t
360
H5VL__common_optional_op(hid_t id, H5I_type_t id_type, H5VL_reg_opt_oper_t reg_opt_op,
361
                         H5VL_optional_args_t *args, hid_t dxpl_id, void **req, H5VL_object_t **_vol_obj_ptr)
362
0
{
363
0
    H5VL_object_t  *tmp_vol_obj = NULL;                                         /* Object for id */
364
0
    H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for id */
365
0
    bool            vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
366
0
    herr_t          ret_value       = SUCCEED; /* Return value */
367
368
0
    FUNC_ENTER_PACKAGE
369
370
    /* Check ID type & get VOL object */
371
0
    if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(id, id_type)))
372
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid identifier");
373
374
    /* Set wrapper info in API context */
375
0
    if (H5VL_set_vol_wrapper(*vol_obj_ptr) < 0)
376
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
377
0
    vol_wrapper_set = true;
378
379
    /* Call the corresponding internal VOL routine */
380
    /* (Must return value from callback, for iterators) */
381
0
    if ((ret_value =
382
0
             (*reg_opt_op)((*vol_obj_ptr)->data, (*vol_obj_ptr)->connector->cls, args, dxpl_id, req)) < 0)
383
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback");
384
385
0
done:
386
    /* Reset object wrapping info in API context */
387
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
388
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
389
390
0
    FUNC_LEAVE_NOAPI(ret_value)
391
0
} /* end H5VL__common_optional_op() */
392
393
/*-------------------------------------------------------------------------
394
 * Function:    H5VL_copy_connector_info
395
 *
396
 * Purpose:     Copy the VOL info for a connector
397
 *
398
 * Return:      Success:    Non-negative
399
 *              Failure:    Negative
400
 *
401
 *-------------------------------------------------------------------------
402
 */
403
herr_t
404
H5VL_copy_connector_info(const H5VL_connector_t *connector, void **dst_info, const void *src_info)
405
0
{
406
0
    void  *new_connector_info = NULL;    /* Copy of connector info */
407
0
    herr_t ret_value          = SUCCEED; /* Return value */
408
409
0
    FUNC_ENTER_NOAPI(FAIL)
410
411
    /* Sanity checks */
412
0
    assert(connector);
413
414
    /* Check for actual source info */
415
0
    if (src_info) {
416
        /* Allow the connector to copy or do it ourselves */
417
0
        if (connector->cls->info_cls.copy) {
418
            /* Prepare & restore library for user callback */
419
0
            H5_BEFORE_USER_CB(FAIL)
420
0
                {
421
0
                    new_connector_info = (connector->cls->info_cls.copy)(src_info);
422
0
                }
423
0
            H5_AFTER_USER_CB(FAIL)
424
0
            if (NULL == new_connector_info)
425
0
                HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "connector info copy callback failed");
426
0
        } /* end if */
427
0
        else if (connector->cls->info_cls.size > 0) {
428
0
            if (NULL == (new_connector_info = H5MM_malloc(connector->cls->info_cls.size)))
429
0
                HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "connector info allocation failed");
430
0
            H5MM_memcpy(new_connector_info, src_info, connector->cls->info_cls.size);
431
0
        } /* end else-if */
432
0
        else
433
0
            HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "no way to copy connector info");
434
0
    } /* end if */
435
436
    /* Set the connector info for the copy */
437
0
    *dst_info = new_connector_info;
438
439
0
done:
440
0
    FUNC_LEAVE_NOAPI(ret_value)
441
0
} /* end H5VL_copy_connector_info() */
442
443
/*---------------------------------------------------------------------------
444
 * Function:    H5VLcopy_connector_info
445
 *
446
 * Purpose:     Copies a VOL connector's info object
447
 *
448
 * Return:      Success:    Non-negative
449
 *              Failure:    Negative
450
 *
451
 *---------------------------------------------------------------------------
452
 */
453
herr_t
454
H5VLcopy_connector_info(hid_t connector_id, void **dst_vol_info, void *src_vol_info)
455
0
{
456
0
    H5VL_connector_t *connector;           /* VOL connector */
457
0
    herr_t            ret_value = SUCCEED; /* Return value */
458
459
0
    FUNC_ENTER_API_NOINIT
460
461
    /* Check args and get VOL connector */
462
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
463
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
464
465
    /* Copy the VOL connector's info object */
466
0
    if (H5VL_copy_connector_info(connector, dst_vol_info, src_vol_info) < 0)
467
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "unable to copy VOL connector info object");
468
469
0
done:
470
0
    FUNC_LEAVE_API_NOINIT(ret_value)
471
0
} /* H5VLcopy_connector_info() */
472
473
/*-------------------------------------------------------------------------
474
 * Function:    H5VL_cmp_connector_info
475
 *
476
 * Purpose:     Compare VOL info for a connector.  Sets *cmp_value to
477
 *              positive if INFO1 is greater than INFO2, negative if
478
 *              INFO2 is greater than INFO1 and zero if INFO1 and
479
 *              INFO2 are equal.
480
 *
481
 * Return:      Success:    Non-negative
482
 *              Failure:    Negative
483
 *
484
 *-------------------------------------------------------------------------
485
 */
486
herr_t
487
H5VL_cmp_connector_info(const H5VL_connector_t *connector, int *cmp_value, const void *info1,
488
                        const void *info2)
489
0
{
490
0
    herr_t ret_value = SUCCEED; /* Return value */
491
492
0
    FUNC_ENTER_NOAPI(FAIL)
493
494
    /* Sanity checks */
495
0
    assert(connector);
496
0
    assert(cmp_value);
497
498
    /* Take care of cases where one or both pointers is NULL */
499
0
    if (info1 == NULL && info2 != NULL) {
500
0
        *cmp_value = -1;
501
0
        HGOTO_DONE(SUCCEED);
502
0
    } /* end if */
503
0
    if (info1 != NULL && info2 == NULL) {
504
0
        *cmp_value = 1;
505
0
        HGOTO_DONE(SUCCEED);
506
0
    } /* end if */
507
0
    if (info1 == NULL && info2 == NULL) {
508
0
        *cmp_value = 0;
509
0
        HGOTO_DONE(SUCCEED);
510
0
    } /* end if */
511
512
    /* Use the class's info comparison routine to compare the info objects,
513
     * if there is a callback, otherwise just compare the info objects as
514
     * memory buffers
515
     */
516
0
    if (connector->cls->info_cls.cmp) {
517
        /* Prepare & restore library for user callback */
518
0
        H5_BEFORE_USER_CB(FAIL)
519
0
            {
520
0
                ret_value = (connector->cls->info_cls.cmp)(cmp_value, info1, info2);
521
0
            }
522
0
        H5_AFTER_USER_CB(FAIL)
523
0
        if (ret_value < 0)
524
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector info");
525
0
    } /* end if */
526
0
    else {
527
0
        assert(connector->cls->info_cls.size > 0);
528
0
        *cmp_value = memcmp(info1, info2, connector->cls->info_cls.size);
529
0
    } /* end else */
530
531
0
done:
532
0
    FUNC_LEAVE_NOAPI(ret_value)
533
0
} /* end H5VL_cmp_connector_info() */
534
535
/*---------------------------------------------------------------------------
536
 * Function:    H5VLcmp_connector_info
537
 *
538
 * Purpose:     Compares two connector info objects
539
 *
540
 * Note:  Both info objects must be from the same VOL connector class
541
 *
542
 * Return:      Success:    Non-negative, with *cmp set to positive if
543
 *          info1 is greater than info2, negative if info2
544
 *          is greater than info1 and zero if info1 and info2
545
 *          are equal.
546
 *              Failure:    Negative
547
 *
548
 *---------------------------------------------------------------------------
549
 */
550
herr_t
551
H5VLcmp_connector_info(int *cmp, hid_t connector_id, const void *info1, const void *info2)
552
0
{
553
0
    H5VL_connector_t *connector;           /* VOL connector */
554
0
    herr_t            ret_value = SUCCEED; /* Return value */
555
556
0
    FUNC_ENTER_API(FAIL)
557
558
    /* Check args and get VOL connector */
559
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
560
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
561
562
    /* Compare the two VOL connector info objects */
563
0
    if (cmp)
564
0
        H5VL_cmp_connector_info(connector, cmp, info1, info2);
565
566
0
done:
567
0
    FUNC_LEAVE_API(ret_value)
568
0
} /* H5VLcmp_connector_info() */
569
570
/*-------------------------------------------------------------------------
571
 * Function:    H5VL_free_connector_info
572
 *
573
 * Purpose:     Free VOL info for a connector
574
 *
575
 * Return:      Success:    Non-negative
576
 *              Failure:    Negative
577
 *
578
 *-------------------------------------------------------------------------
579
 */
580
herr_t
581
H5VL_free_connector_info(const H5VL_connector_t *connector, const void *info)
582
0
{
583
0
    herr_t ret_value = SUCCEED; /* Return value */
584
585
0
    FUNC_ENTER_NOAPI(FAIL)
586
587
    /* Sanity check */
588
0
    assert(connector);
589
590
    /* Only free info object, if it's non-NULL */
591
0
    if (info) {
592
        /* Allow the connector to free info or do it ourselves */
593
0
        if (connector->cls->info_cls.free) {
594
            /* Prepare & restore library for user callback */
595
0
            H5_BEFORE_USER_CB(FAIL)
596
0
                {
597
                    /* Cast through uintptr_t to de-const memory */
598
0
                    ret_value = (connector->cls->info_cls.free)((void *)(uintptr_t)info);
599
0
                }
600
0
            H5_AFTER_USER_CB(FAIL)
601
0
            if (ret_value < 0)
602
0
                HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "connector info free request failed");
603
0
        }
604
0
        else
605
0
            H5MM_xfree_const(info);
606
0
    }
607
608
0
done:
609
0
    FUNC_LEAVE_NOAPI(ret_value)
610
0
} /* end H5VL_free_connector_info() */
611
612
/*---------------------------------------------------------------------------
613
 * Function:    H5VLfree_connector_info
614
 *
615
 * Purpose:     Free VOL connector info object
616
 *
617
 * Return:      Success:    Non-negative
618
 *              Failure:    Negative
619
 *
620
 *---------------------------------------------------------------------------
621
 */
622
herr_t
623
H5VLfree_connector_info(hid_t connector_id, void *info)
624
0
{
625
0
    H5VL_connector_t *connector;           /* VOL connector */
626
0
    herr_t            ret_value = SUCCEED; /* Return value */
627
628
0
    FUNC_ENTER_API_NOINIT
629
630
    /* Check args and get VOL connector */
631
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
632
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
633
634
    /* Free the VOL connector info object */
635
0
    if (H5VL_free_connector_info(connector, info) < 0)
636
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL connector info object");
637
638
0
done:
639
0
    FUNC_LEAVE_API_NOINIT(ret_value)
640
0
} /* H5VLfree_connector_info() */
641
642
/*---------------------------------------------------------------------------
643
 * Function:    H5VLconnector_info_to_str
644
 *
645
 * Purpose:     Serialize a connector's info into a string
646
 *
647
 * Return:      Success:    Non-negative
648
 *              Failure:    Negative
649
 *
650
 *---------------------------------------------------------------------------
651
 */
652
herr_t
653
H5VLconnector_info_to_str(const void *info, hid_t connector_id, char **str)
654
0
{
655
0
    herr_t ret_value = SUCCEED; /* Return value */
656
657
0
    FUNC_ENTER_API_NOINIT
658
659
    /* Only serialize info object, if it's non-NULL */
660
0
    if (info) {
661
0
        H5VL_connector_t *connector; /* VOL connector */
662
663
        /* Check args and get connector pointer */
664
0
        if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
665
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
666
667
        /* Allow the connector to serialize info */
668
0
        if (connector->cls->info_cls.to_str) {
669
            /* Prepare & restore library for user callback */
670
0
            H5_BEFORE_USER_CB(FAIL)
671
0
                {
672
0
                    ret_value = (connector->cls->info_cls.to_str)(info, str);
673
0
                }
674
0
            H5_AFTER_USER_CB(FAIL)
675
0
            if (ret_value < 0)
676
0
                HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "can't serialize connector info");
677
0
        } /* end if */
678
0
        else
679
0
            *str = NULL;
680
0
    } /* end if */
681
0
    else
682
0
        *str = NULL;
683
684
0
done:
685
0
    FUNC_LEAVE_API_NOINIT(ret_value)
686
0
} /* H5VLconnector_info_to_str() */
687
688
/*-------------------------------------------------------------------------
689
 * Function:    H5VL__connector_str_to_info
690
 *
691
 * Purpose:     Deserializes a string into a connector's info object
692
 *
693
 * Return:      Success:    Non-negative
694
 *              Failure:    Negative
695
 *
696
 *-------------------------------------------------------------------------
697
 */
698
herr_t
699
H5VL__connector_str_to_info(const char *str, H5VL_connector_t *connector, void **info)
700
0
{
701
0
    herr_t ret_value = SUCCEED; /* Return value */
702
703
0
    FUNC_ENTER_PACKAGE
704
705
    /* Only deserialize string, if it's non-NULL */
706
0
    if (str) {
707
        /* Allow the connector to deserialize info */
708
0
        if (connector->cls->info_cls.from_str) {
709
            /* Prepare & restore library for user callback */
710
0
            H5_BEFORE_USER_CB(FAIL)
711
0
                {
712
0
                    ret_value = (connector->cls->info_cls.from_str)(str, info);
713
0
                }
714
0
            H5_AFTER_USER_CB(FAIL)
715
0
            if (ret_value < 0)
716
0
                HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize connector info");
717
0
        } /* end if */
718
0
        else
719
0
            *info = NULL;
720
0
    } /* end if */
721
0
    else
722
0
        *info = NULL;
723
724
0
done:
725
0
    FUNC_LEAVE_NOAPI(ret_value)
726
0
} /* end H5VL__connector_str_to_info() */
727
728
/*---------------------------------------------------------------------------
729
 * Function:    H5VLconnector_str_to_info
730
 *
731
 * Purpose:     Deserialize a string into a connector's info
732
 *
733
 * Return:      Success:    Non-negative
734
 *              Failure:    Negative
735
 *
736
 *---------------------------------------------------------------------------
737
 */
738
herr_t
739
H5VLconnector_str_to_info(const char *str, hid_t connector_id, void **info /*out*/)
740
0
{
741
0
    H5VL_connector_t *connector = NULL;
742
0
    herr_t            ret_value = SUCCEED; /* Return value */
743
744
0
    FUNC_ENTER_API_NOINIT
745
746
    /* Check args and get VOL connector */
747
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
748
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
749
750
    /* Call internal routine */
751
0
    if (H5VL__connector_str_to_info(str, connector, info) < 0)
752
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTDECODE, FAIL, "can't deserialize connector info");
753
754
0
done:
755
0
    FUNC_LEAVE_API_NOINIT(ret_value)
756
0
} /* H5VLconnector_str_to_info() */
757
758
/*---------------------------------------------------------------------------
759
 * Function:    H5VLget_object
760
 *
761
 * Purpose:     Retrieves an underlying object.
762
 *
763
 * Return:      Success:    Non-NULL
764
 *              Failure:    NULL
765
 *
766
 *---------------------------------------------------------------------------
767
 */
768
void *
769
H5VLget_object(void *obj, hid_t connector_id)
770
0
{
771
0
    H5VL_connector_t *connector;        /* VOL connector */
772
0
    void             *ret_value = NULL; /* Return value */
773
774
0
    FUNC_ENTER_API_NOINIT
775
776
    /* Check args */
777
0
    if (NULL == obj)
778
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
779
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
780
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
781
782
    /* Check for 'get_object' callback in connector */
783
0
    if (connector->cls->wrap_cls.get_object) {
784
        /* Prepare & restore library for user callback */
785
0
        H5_BEFORE_USER_CB(NULL)
786
0
            {
787
0
                ret_value = (connector->cls->wrap_cls.get_object)(obj);
788
0
            }
789
0
        H5_AFTER_USER_CB(NULL)
790
0
    }
791
0
    else
792
0
        ret_value = obj;
793
794
0
done:
795
0
    FUNC_LEAVE_API_NOINIT(ret_value)
796
0
} /* H5VLget_object */
797
798
/*---------------------------------------------------------------------------
799
 * Function:    H5VLget_wrap_ctx
800
 *
801
 * Purpose:     Get a VOL connector's object wrapping context. The output
802
 *              wrap context is stored in memory allocated by the VOL callback
803
 *              under *wrap_ctx and must be freed by the caller through
804
 *              H5VLfree_wrap_ctx().
805
 *
806
 * Return:      Success:    Non-negative
807
 *              Failure:    Negative
808
 *
809
 *---------------------------------------------------------------------------
810
 */
811
herr_t
812
H5VLget_wrap_ctx(void *obj, hid_t connector_id, void **wrap_ctx /*out*/)
813
0
{
814
0
    H5VL_connector_t *connector;           /* VOL connector */
815
0
    herr_t            ret_value = SUCCEED; /* Return value */
816
817
0
    FUNC_ENTER_API_NOINIT
818
819
    /* Check args and get connector pointer */
820
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
821
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
822
823
    /* Allow the connector to wrap */
824
0
    if (connector->cls->wrap_cls.get_wrap_ctx) {
825
        /* Sanity check */
826
0
        assert(connector->cls->wrap_cls.free_wrap_ctx);
827
828
        /* Prepare & restore library for user callback */
829
0
        H5_BEFORE_USER_CB(FAIL)
830
0
            {
831
                /* Invoke connector's callback */
832
0
                ret_value = (connector->cls->wrap_cls.get_wrap_ctx)(obj, wrap_ctx);
833
0
            }
834
0
        H5_AFTER_USER_CB(FAIL)
835
0
        if (ret_value < 0)
836
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "connector wrap context callback failed");
837
0
    } /* end if */
838
0
    else
839
0
        *wrap_ctx = NULL;
840
841
0
done:
842
0
    FUNC_LEAVE_API_NOINIT(ret_value)
843
0
} /* H5VLget_wrap_ctx() */
844
845
/*-------------------------------------------------------------------------
846
 * Function:    H5VL_wrap_object
847
 *
848
 * Purpose:     Wrap an object with connector
849
 *
850
 * Return:      Success:    Non-NULL
851
 *              Failure:    NULL
852
 *
853
 *-------------------------------------------------------------------------
854
 */
855
void *
856
H5VL_wrap_object(const H5VL_class_t *cls, void *wrap_ctx, void *obj, H5I_type_t obj_type)
857
673
{
858
673
    void *ret_value = NULL; /* Return value */
859
860
673
    FUNC_ENTER_NOAPI(NULL)
861
862
    /* Sanity checks */
863
673
    assert(cls);
864
673
    assert(obj);
865
866
    /* Only wrap object if there's a wrap context */
867
673
    if (wrap_ctx) {
868
        /* Prepare & restore library for user callback */
869
0
        H5_BEFORE_USER_CB(NULL)
870
0
            {
871
                /* Ask the connector to wrap the object */
872
0
                ret_value = (cls->wrap_cls.wrap_object)(obj, obj_type, wrap_ctx);
873
0
            }
874
0
        H5_AFTER_USER_CB(NULL)
875
0
        if (NULL == ret_value)
876
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't wrap object");
877
0
    } /* end if */
878
673
    else
879
673
        ret_value = obj;
880
881
673
done:
882
673
    FUNC_LEAVE_NOAPI(ret_value)
883
673
} /* end H5VL_wrap_object() */
884
885
/*---------------------------------------------------------------------------
886
 * Function:    H5VLwrap_object
887
 *
888
 * Purpose:     Asks a connector to wrap an underlying object.
889
 *
890
 * Return:      Success:    Non-NULL
891
 *              Failure:    NULL
892
 *
893
 *---------------------------------------------------------------------------
894
 */
895
void *
896
H5VLwrap_object(void *obj, H5I_type_t obj_type, hid_t connector_id, void *wrap_ctx)
897
0
{
898
0
    H5VL_connector_t *connector;        /* VOL connector */
899
0
    void             *ret_value = NULL; /* Return value */
900
901
0
    FUNC_ENTER_API_NOINIT
902
903
    /* Check args and get connector pointer */
904
0
    if (NULL == obj)
905
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
906
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
907
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
908
909
    /* Wrap the object */
910
0
    if (NULL == (ret_value = H5VL_wrap_object(connector->cls, wrap_ctx, obj, obj_type)))
911
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to wrap object");
912
913
0
done:
914
0
    FUNC_LEAVE_API_NOINIT(ret_value)
915
0
} /* H5VLwrap_object */
916
917
/*-------------------------------------------------------------------------
918
 * Function:    H5VL_unwrap_object
919
 *
920
 * Purpose:     Unwrap an object from connector
921
 *
922
 * Return:      Success:    Non-NULL
923
 *              Failure:    NULL
924
 *
925
 *-------------------------------------------------------------------------
926
 */
927
void *
928
H5VL_unwrap_object(const H5VL_class_t *cls, void *obj)
929
673
{
930
673
    void *ret_value = NULL; /* Return value */
931
932
673
    FUNC_ENTER_NOAPI(NULL)
933
934
    /* Sanity checks */
935
673
    assert(cls);
936
673
    assert(obj);
937
938
    /* Only unwrap object if there's an unwrap callback */
939
673
    if (cls->wrap_cls.wrap_object) {
940
        /* Prepare & restore library for user callback */
941
0
        H5_BEFORE_USER_CB(NULL)
942
0
            {
943
                /* Ask the connector to unwrap the object */
944
0
                ret_value = (cls->wrap_cls.unwrap_object)(obj);
945
0
            }
946
0
        H5_AFTER_USER_CB(NULL)
947
0
        if (NULL == ret_value)
948
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't unwrap object");
949
0
    } /* end if */
950
673
    else
951
673
        ret_value = obj;
952
953
673
done:
954
673
    FUNC_LEAVE_NOAPI(ret_value)
955
673
} /* end H5VL_unwrap_object() */
956
957
/*---------------------------------------------------------------------------
958
 * Function:    H5VLunwrap_object
959
 *
960
 * Purpose:     Unwrap an object from connector
961
 *
962
 * Return:      Success:    Non-NULL
963
 *              Failure:    NULL
964
 *
965
 *---------------------------------------------------------------------------
966
 */
967
void *
968
H5VLunwrap_object(void *obj, hid_t connector_id)
969
0
{
970
0
    H5VL_connector_t *connector;        /* VOL connector */
971
0
    void             *ret_value = NULL; /* Return value */
972
973
0
    FUNC_ENTER_API_NOINIT
974
975
    /* Check args and get connector pointer */
976
0
    if (NULL == obj)
977
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
978
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
979
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
980
981
    /* Unwrap the object */
982
0
    if (NULL == (ret_value = H5VL_unwrap_object(connector->cls, obj)))
983
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to unwrap object");
984
985
0
done:
986
0
    FUNC_LEAVE_API_NOINIT(ret_value)
987
0
} /* H5VLunwrap_object */
988
989
/*---------------------------------------------------------------------------
990
 * Function:    H5VLfree_wrap_ctx
991
 *
992
 * Purpose:     Release a VOL connector's object wrapping context
993
 *
994
 * Return:      Success:    Non-negative
995
 *              Failure:    Negative
996
 *
997
 *---------------------------------------------------------------------------
998
 */
999
herr_t
1000
H5VLfree_wrap_ctx(void *wrap_ctx, hid_t connector_id)
1001
0
{
1002
0
    H5VL_connector_t *connector;           /* VOL connector */
1003
0
    herr_t            ret_value = SUCCEED; /* Return value */
1004
1005
0
    FUNC_ENTER_API_NOINIT
1006
1007
    /* Check args and get connector pointer */
1008
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1009
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
1010
1011
    /* Only free wrap context, if it's non-NULL */
1012
0
    if (wrap_ctx) {
1013
        /* Prepare & restore library for user callback */
1014
0
        H5_BEFORE_USER_CB(FAIL)
1015
0
            {
1016
                /* Free the connector's object wrapping context */
1017
0
                ret_value = (connector->cls->wrap_cls.free_wrap_ctx)(wrap_ctx);
1018
0
            }
1019
0
        H5_AFTER_USER_CB(FAIL)
1020
0
        if (ret_value < 0)
1021
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "connector wrap context free request failed");
1022
0
    } /* end if */
1023
1024
0
done:
1025
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1026
0
} /* H5VLfree_wrap_ctx() */
1027
1028
/*-------------------------------------------------------------------------
1029
 * Function:    H5VL__attr_create
1030
 *
1031
 * Purpose:     Creates an attribute through the VOL
1032
 *
1033
 * Return:      Success: Pointer to the new attribute
1034
 *              Failure: NULL
1035
 *
1036
 *-------------------------------------------------------------------------
1037
 */
1038
static void *
1039
H5VL__attr_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name,
1040
                  hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req)
1041
0
{
1042
0
    void *ret_value = NULL; /* Return value */
1043
1044
0
    FUNC_ENTER_PACKAGE
1045
1046
    /* Check if the corresponding VOL callback exists */
1047
0
    if (NULL == cls->attr_cls.create)
1048
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'attr create' method");
1049
1050
    /* Prepare & restore library for user callback */
1051
0
    H5_BEFORE_USER_CB(NULL)
1052
0
        {
1053
            /* Call the corresponding VOL callback */
1054
0
            ret_value = (cls->attr_cls.create)(obj, loc_params, name, type_id, space_id, acpl_id, aapl_id,
1055
0
                                               dxpl_id, req);
1056
0
        }
1057
0
    H5_AFTER_USER_CB(NULL)
1058
0
    if (NULL == ret_value)
1059
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "attribute create failed");
1060
1061
0
done:
1062
0
    FUNC_LEAVE_NOAPI(ret_value)
1063
0
} /* end H5VL__attr_create() */
1064
1065
/*-------------------------------------------------------------------------
1066
 * Function:    H5VL_attr_create
1067
 *
1068
 * Purpose:     Creates an attribute through the VOL
1069
 *
1070
 * Return:      Success: Pointer to the new attribute
1071
 *              Failure: NULL
1072
 *
1073
 *-------------------------------------------------------------------------
1074
 */
1075
void *
1076
H5VL_attr_create(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
1077
                 hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req)
1078
0
{
1079
0
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
1080
0
    void *ret_value       = NULL;  /* Return value */
1081
1082
0
    FUNC_ENTER_NOAPI(NULL)
1083
1084
    /* Set wrapper info in API context */
1085
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1086
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
1087
0
    vol_wrapper_set = true;
1088
1089
    /* Call the corresponding internal VOL routine */
1090
0
    if (NULL == (ret_value = H5VL__attr_create(vol_obj->data, loc_params, vol_obj->connector->cls, name,
1091
0
                                               type_id, space_id, acpl_id, aapl_id, dxpl_id, req)))
1092
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "attribute create failed");
1093
1094
0
done:
1095
    /* Reset object wrapping info in API context */
1096
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1097
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
1098
1099
0
    FUNC_LEAVE_NOAPI(ret_value)
1100
0
} /* end H5VL_attr_create() */
1101
1102
/*-------------------------------------------------------------------------
1103
 * Function:    H5VLattr_create
1104
 *
1105
 * Purpose:     Creates an attribute
1106
 *
1107
 * Return:      Success:    Pointer to the new attribute
1108
 *              Failure:    NULL
1109
 *
1110
 *-------------------------------------------------------------------------
1111
 */
1112
void *
1113
H5VLattr_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
1114
                hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id,
1115
                void **req /*out*/)
1116
0
{
1117
0
    H5VL_connector_t *connector;        /* VOL connector */
1118
0
    void             *ret_value = NULL; /* Return value */
1119
1120
0
    FUNC_ENTER_API_NOINIT
1121
1122
    /* Check args and get connector pointer */
1123
0
    if (NULL == obj)
1124
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
1125
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1126
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
1127
1128
    /* Call the corresponding internal VOL routine */
1129
0
    if (NULL == (ret_value = H5VL__attr_create(obj, loc_params, connector->cls, name, type_id, space_id,
1130
0
                                               acpl_id, aapl_id, dxpl_id, req)))
1131
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "unable to create attribute");
1132
1133
0
done:
1134
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1135
0
} /* end H5VLattr_create() */
1136
1137
/*-------------------------------------------------------------------------
1138
 * Function:  H5VL__attr_open
1139
 *
1140
 * Purpose: Opens an attribute through the VOL
1141
 *
1142
 * Return:      Success: Pointer to the attribute
1143
 *    Failure: NULL
1144
 *
1145
 *-------------------------------------------------------------------------
1146
 */
1147
static void *
1148
H5VL__attr_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name,
1149
                hid_t aapl_id, hid_t dxpl_id, void **req)
1150
68
{
1151
68
    void *ret_value = NULL; /* Return value */
1152
1153
68
    FUNC_ENTER_PACKAGE
1154
1155
    /* Check if the corresponding VOL callback exists */
1156
68
    if (NULL == cls->attr_cls.open)
1157
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'attr open' method");
1158
1159
    /* Prepare & restore library for user callback */
1160
68
    H5_BEFORE_USER_CB(NULL)
1161
68
        {
1162
            /* Call the corresponding VOL open callback */
1163
68
            ret_value = (cls->attr_cls.open)(obj, loc_params, name, aapl_id, dxpl_id, req);
1164
68
        }
1165
68
    H5_AFTER_USER_CB(NULL)
1166
68
    if (NULL == ret_value)
1167
68
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "attribute open failed");
1168
1169
68
done:
1170
68
    FUNC_LEAVE_NOAPI(ret_value)
1171
68
} /* end H5VL__attr_open() */
1172
1173
/*-------------------------------------------------------------------------
1174
 * Function:  H5VL_attr_open
1175
 *
1176
 * Purpose: Opens an attribute through the VOL
1177
 *
1178
 * Return:      Success: Pointer to the attribute
1179
 *    Failure: NULL
1180
 *
1181
 *-------------------------------------------------------------------------
1182
 */
1183
void *
1184
H5VL_attr_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
1185
               hid_t aapl_id, hid_t dxpl_id, void **req)
1186
68
{
1187
68
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
1188
68
    void *ret_value       = NULL;  /* Return value */
1189
1190
68
    FUNC_ENTER_NOAPI(NULL)
1191
1192
    /* Set wrapper info in API context */
1193
68
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1194
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
1195
68
    vol_wrapper_set = true;
1196
1197
    /* Call the corresponding internal VOL routine */
1198
68
    if (NULL == (ret_value = H5VL__attr_open(vol_obj->data, loc_params, vol_obj->connector->cls, name,
1199
68
                                             aapl_id, dxpl_id, req)))
1200
68
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "attribute open failed");
1201
1202
68
done:
1203
    /* Reset object wrapping info in API context */
1204
68
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1205
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
1206
1207
68
    FUNC_LEAVE_NOAPI(ret_value)
1208
68
} /* end H5VL_attr_open() */
1209
1210
/*-------------------------------------------------------------------------
1211
 * Function:  H5VLattr_open
1212
 *
1213
 * Purpose:     Opens an attribute
1214
 *
1215
 * Return:      Success:    Pointer to the attribute
1216
 *              Failure:    NULL
1217
 *
1218
 *-------------------------------------------------------------------------
1219
 */
1220
void *
1221
H5VLattr_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
1222
              hid_t aapl_id, hid_t dxpl_id, void **req /*out*/)
1223
0
{
1224
0
    H5VL_connector_t *connector;        /* VOL connector */
1225
0
    void             *ret_value = NULL; /* Return value */
1226
1227
0
    FUNC_ENTER_API_NOINIT
1228
1229
    /* Check args and get connector pointer */
1230
0
    if (NULL == obj)
1231
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
1232
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1233
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
1234
1235
    /* Call the corresponding internal VOL routine */
1236
0
    if (NULL == (ret_value = H5VL__attr_open(obj, loc_params, connector->cls, name, aapl_id, dxpl_id, req)))
1237
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "unable to open attribute");
1238
1239
0
done:
1240
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1241
0
} /* end H5VLattr_open() */
1242
1243
/*-------------------------------------------------------------------------
1244
 * Function:  H5VL__attr_read
1245
 *
1246
 * Purpose: Reads data from attr through the VOL
1247
 *
1248
 * Return:      Success:    Non-negative
1249
 *              Failure:    Negative
1250
 *
1251
 *-------------------------------------------------------------------------
1252
 */
1253
static herr_t
1254
H5VL__attr_read(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req)
1255
0
{
1256
0
    herr_t ret_value = SUCCEED; /* Return value */
1257
1258
0
    FUNC_ENTER_PACKAGE
1259
1260
    /* Check if the corresponding VOL callback exists */
1261
0
    if (NULL == cls->attr_cls.read)
1262
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr read' method");
1263
1264
    /* Prepare & restore library for user callback */
1265
0
    H5_BEFORE_USER_CB(FAIL)
1266
0
        {
1267
            /* Call the corresponding VOL callback */
1268
0
            ret_value = (cls->attr_cls.read)(obj, mem_type_id, buf, dxpl_id, req);
1269
0
        }
1270
0
    H5_AFTER_USER_CB(FAIL)
1271
0
    if (ret_value < 0)
1272
0
        HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "attribute read failed");
1273
1274
0
done:
1275
0
    FUNC_LEAVE_NOAPI(ret_value)
1276
0
} /* end H5VL__attr_read() */
1277
1278
/*-------------------------------------------------------------------------
1279
 * Function:  H5VL_attr_read
1280
 *
1281
 * Purpose: Reads data from attr through the VOL
1282
 *
1283
 * Return:      Success:    Non-negative
1284
 *              Failure:    Negative
1285
 *
1286
 *-------------------------------------------------------------------------
1287
 */
1288
herr_t
1289
H5VL_attr_read(const H5VL_object_t *vol_obj, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req)
1290
0
{
1291
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
1292
0
    herr_t ret_value       = SUCCEED; /* Return value */
1293
1294
0
    FUNC_ENTER_NOAPI(FAIL)
1295
1296
    /* Set wrapper info in API context */
1297
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1298
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
1299
0
    vol_wrapper_set = true;
1300
1301
    /* Call the corresponding internal VOL routine */
1302
0
    if (H5VL__attr_read(vol_obj->data, vol_obj->connector->cls, mem_type_id, buf, dxpl_id, req) < 0)
1303
0
        HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "attribute read failed");
1304
1305
0
done:
1306
    /* Reset object wrapping info in API context */
1307
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1308
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
1309
1310
0
    FUNC_LEAVE_NOAPI(ret_value)
1311
0
} /* end H5VL_attr_read() */
1312
1313
/*-------------------------------------------------------------------------
1314
 * Function:    H5VLattr_read
1315
 *
1316
 * Purpose:     Reads data from an attribute
1317
 *
1318
 * Return:      Success:    Non-negative
1319
 *              Failure:    Negative
1320
 *
1321
 *-------------------------------------------------------------------------
1322
 */
1323
herr_t
1324
H5VLattr_read(void *obj, hid_t connector_id, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req /*out*/)
1325
0
{
1326
0
    H5VL_connector_t *connector;           /* VOL connector */
1327
0
    herr_t            ret_value = SUCCEED; /* Return value */
1328
1329
0
    FUNC_ENTER_API_NOINIT
1330
1331
    /* Check args and get connector pointer */
1332
0
    if (NULL == obj)
1333
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
1334
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1335
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
1336
1337
    /* Call the corresponding internal VOL routine */
1338
0
    if (H5VL__attr_read(obj, connector->cls, mem_type_id, buf, dxpl_id, req) < 0)
1339
0
        HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "unable to read attribute");
1340
1341
0
done:
1342
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1343
0
} /* end H5VLattr_read() */
1344
1345
/*-------------------------------------------------------------------------
1346
 * Function:  H5VL__attr_write
1347
 *
1348
 * Purpose: Writes data to attr through the VOL
1349
 *
1350
 * Return:      Success:    Non-negative
1351
 *              Failure:    Negative
1352
 *
1353
 *-------------------------------------------------------------------------
1354
 */
1355
static herr_t
1356
H5VL__attr_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, const void *buf, hid_t dxpl_id,
1357
                 void **req)
1358
0
{
1359
0
    herr_t ret_value = SUCCEED; /* Return value */
1360
1361
0
    FUNC_ENTER_PACKAGE
1362
1363
    /* Check if the corresponding VOL callback exists */
1364
0
    if (NULL == cls->attr_cls.write)
1365
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr write' method");
1366
1367
    /* Prepare & restore library for user callback */
1368
0
    H5_BEFORE_USER_CB(FAIL)
1369
0
        {
1370
            /* Call the corresponding VOL callback */
1371
0
            ret_value = (cls->attr_cls.write)(obj, mem_type_id, buf, dxpl_id, req);
1372
0
        }
1373
0
    H5_AFTER_USER_CB(FAIL)
1374
0
    if (ret_value < 0)
1375
0
        HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "write failed");
1376
1377
0
done:
1378
0
    FUNC_LEAVE_NOAPI(ret_value)
1379
0
} /* end H5VL__attr_write() */
1380
1381
/*-------------------------------------------------------------------------
1382
 * Function:  H5VL_attr_write
1383
 *
1384
 * Purpose: Writes data to attr through the VOL
1385
 *
1386
 * Return:      Success:    Non-negative
1387
 *              Failure:    Negative
1388
 *
1389
 *-------------------------------------------------------------------------
1390
 */
1391
herr_t
1392
H5VL_attr_write(const H5VL_object_t *vol_obj, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req)
1393
0
{
1394
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
1395
0
    herr_t ret_value       = SUCCEED; /* Return value */
1396
1397
0
    FUNC_ENTER_NOAPI(FAIL)
1398
1399
    /* Set wrapper info in API context */
1400
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1401
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
1402
0
    vol_wrapper_set = true;
1403
1404
    /* Call the corresponding internal VOL routine */
1405
0
    if (H5VL__attr_write(vol_obj->data, vol_obj->connector->cls, mem_type_id, buf, dxpl_id, req) < 0)
1406
0
        HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "write failed");
1407
1408
0
done:
1409
    /* Reset object wrapping info in API context */
1410
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1411
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
1412
1413
0
    FUNC_LEAVE_NOAPI(ret_value)
1414
0
} /* end H5VL_attr_write() */
1415
1416
/*-------------------------------------------------------------------------
1417
 * Function:    H5VLattr_write
1418
 *
1419
 * Purpose:     Writes data to an attribute
1420
 *
1421
 * Return:      Success:    Non-negative
1422
 *              Failure:    Negative
1423
 *
1424
 *-------------------------------------------------------------------------
1425
 */
1426
herr_t
1427
H5VLattr_write(void *obj, hid_t connector_id, hid_t mem_type_id, const void *buf, hid_t dxpl_id,
1428
               void **req /*out*/)
1429
0
{
1430
0
    H5VL_connector_t *connector;           /* VOL connector */
1431
0
    herr_t            ret_value = SUCCEED; /* Return value */
1432
1433
0
    FUNC_ENTER_API_NOINIT
1434
1435
    /* Check args and get connector pointer */
1436
0
    if (NULL == obj)
1437
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
1438
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1439
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
1440
1441
    /* Call the corresponding internal VOL routine */
1442
0
    if (H5VL__attr_write(obj, connector->cls, mem_type_id, buf, dxpl_id, req) < 0)
1443
0
        HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "unable to write attribute");
1444
1445
0
done:
1446
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1447
0
} /* end H5VLattr_write() */
1448
1449
/*-------------------------------------------------------------------------
1450
 * Function:  H5VL__attr_get
1451
 *
1452
 * Purpose: Get specific information about the attribute through the VOL
1453
 *
1454
 * Return:      Success:    Non-negative
1455
 *              Failure:    Negative
1456
 *
1457
 *-------------------------------------------------------------------------
1458
 */
1459
static herr_t
1460
H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req)
1461
0
{
1462
0
    herr_t ret_value = SUCCEED; /* Return value */
1463
1464
0
    FUNC_ENTER_PACKAGE
1465
1466
    /* Check if the corresponding VOL callback exists */
1467
0
    if (NULL == cls->attr_cls.get)
1468
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr get' method");
1469
1470
    /* Prepare & restore library for user callback */
1471
0
    H5_BEFORE_USER_CB(FAIL)
1472
0
        {
1473
            /* Call the corresponding VOL callback */
1474
0
            ret_value = (cls->attr_cls.get)(obj, args, dxpl_id, req);
1475
0
        }
1476
0
    H5_AFTER_USER_CB(FAIL)
1477
0
    if (ret_value < 0)
1478
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "attribute get failed");
1479
1480
0
done:
1481
0
    FUNC_LEAVE_NOAPI(ret_value)
1482
0
} /* end H5VL__attr_get() */
1483
1484
/*-------------------------------------------------------------------------
1485
 * Function:  H5VL_attr_get
1486
 *
1487
 * Purpose: Get specific information about the attribute through the VOL
1488
 *
1489
 * Return:      Success:    Non-negative
1490
 *              Failure:    Negative
1491
 *
1492
 *-------------------------------------------------------------------------
1493
 */
1494
herr_t
1495
H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req)
1496
0
{
1497
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
1498
0
    herr_t ret_value       = SUCCEED; /* Return value */
1499
1500
0
    FUNC_ENTER_NOAPI(FAIL)
1501
1502
    /* Set wrapper info in API context */
1503
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1504
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
1505
0
    vol_wrapper_set = true;
1506
1507
    /* Call the corresponding internal VOL routine */
1508
0
    if (H5VL__attr_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
1509
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "attribute get failed");
1510
1511
0
done:
1512
    /* Reset object wrapping info in API context */
1513
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1514
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
1515
1516
0
    FUNC_LEAVE_NOAPI(ret_value)
1517
0
} /* end H5VL_attr_get() */
1518
1519
/*-------------------------------------------------------------------------
1520
 * Function:    H5VLattr_get
1521
 *
1522
 * Purpose:     Gets information about the attribute
1523
 *
1524
 * Return:      Success:    Non-negative
1525
 *              Failure:    Negative
1526
 *
1527
 *-------------------------------------------------------------------------
1528
 */
1529
herr_t
1530
H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req /*out*/)
1531
0
{
1532
0
    H5VL_connector_t *connector;           /* VOL connector */
1533
0
    herr_t            ret_value = SUCCEED; /* Return value */
1534
1535
0
    FUNC_ENTER_API_NOINIT
1536
1537
    /* Check args and get connector pointer */
1538
0
    if (NULL == obj)
1539
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
1540
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1541
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
1542
0
    if (NULL == args)
1543
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument struct");
1544
1545
    /* Call the corresponding internal VOL routine */
1546
0
    if (H5VL__attr_get(obj, connector->cls, args, dxpl_id, req) < 0)
1547
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to get attribute information");
1548
1549
0
done:
1550
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1551
0
} /* end H5VLattr_get() */
1552
1553
/*-------------------------------------------------------------------------
1554
 * Function:  H5VL__attr_specific
1555
 *
1556
 * Purpose: Specific operation on attributes through the VOL
1557
 *
1558
 * Return:      Success:    Non-negative
1559
 *              Failure:    Negative
1560
 *
1561
 *-------------------------------------------------------------------------
1562
 */
1563
static herr_t
1564
H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
1565
                    H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req)
1566
0
{
1567
0
    herr_t ret_value = SUCCEED; /* Return value */
1568
1569
0
    FUNC_ENTER_PACKAGE
1570
1571
    /* Check if the corresponding VOL callback exists */
1572
0
    if (NULL == cls->attr_cls.specific)
1573
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr specific' method");
1574
1575
    /* Prepare & restore library for user callback */
1576
0
    H5_BEFORE_USER_CB(FAIL)
1577
0
        {
1578
            /* Call the corresponding VOL callback */
1579
            /* (Must return value from callback, for iterators) */
1580
0
            ret_value = (cls->attr_cls.specific)(obj, loc_params, args, dxpl_id, req);
1581
0
        }
1582
0
    H5_AFTER_USER_CB(FAIL)
1583
0
    if (ret_value < 0)
1584
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback");
1585
1586
0
done:
1587
0
    FUNC_LEAVE_NOAPI(ret_value)
1588
0
} /* end H5VL__attr_specific() */
1589
1590
/*-------------------------------------------------------------------------
1591
 * Function:  H5VL_attr_specific
1592
 *
1593
 * Purpose: Specific operation on attributes through the VOL
1594
 *
1595
 * Return:      Success:    Non-negative
1596
 *              Failure:    Negative
1597
 *
1598
 *-------------------------------------------------------------------------
1599
 */
1600
herr_t
1601
H5VL_attr_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params,
1602
                   H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req)
1603
0
{
1604
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
1605
0
    herr_t ret_value       = SUCCEED; /* Return value */
1606
1607
0
    FUNC_ENTER_NOAPI(FAIL)
1608
1609
    /* Set wrapper info in API context */
1610
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1611
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
1612
0
    vol_wrapper_set = true;
1613
1614
    /* Call the corresponding internal VOL routine */
1615
    /* (Must return value from callback, for iterators) */
1616
0
    if ((ret_value =
1617
0
             H5VL__attr_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req)) < 0)
1618
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback");
1619
1620
0
done:
1621
    /* Reset object wrapping info in API context */
1622
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1623
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
1624
1625
0
    FUNC_LEAVE_NOAPI(ret_value)
1626
0
} /* end H5VL_attr_specific() */
1627
1628
/*-------------------------------------------------------------------------
1629
 * Function:    H5VLattr_specific
1630
 *
1631
 * Purpose:     Performs a connector-specific operation on an attribute
1632
 *
1633
 * Return:      Success:    Non-negative
1634
 *              Failure:    Negative
1635
 *
1636
 *-------------------------------------------------------------------------
1637
 */
1638
herr_t
1639
H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id,
1640
                  H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req /*out*/)
1641
0
{
1642
0
    H5VL_connector_t *connector;           /* VOL connector */
1643
0
    herr_t            ret_value = SUCCEED; /* Return value */
1644
1645
0
    FUNC_ENTER_API_NOINIT
1646
1647
    /* Check args and get connector pointer */
1648
0
    if (NULL == obj)
1649
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
1650
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1651
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
1652
1653
    /* Call the corresponding internal VOL routine */
1654
    /* (Must return value from callback, for iterators) */
1655
0
    if ((ret_value = H5VL__attr_specific(obj, loc_params, connector->cls, args, dxpl_id, req)) < 0)
1656
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback");
1657
1658
0
done:
1659
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1660
0
} /* end H5VLattr_specific() */
1661
1662
/*-------------------------------------------------------------------------
1663
 * Function:  H5VL__attr_optional
1664
 *
1665
 * Purpose: Optional operation specific to connectors.
1666
 *
1667
 * Return:      Success:    Non-negative
1668
 *              Failure:    Negative
1669
 *
1670
 *-------------------------------------------------------------------------
1671
 */
1672
static herr_t
1673
H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
1674
0
{
1675
0
    herr_t ret_value = SUCCEED; /* Return value */
1676
1677
0
    FUNC_ENTER_PACKAGE
1678
1679
    /* Check if the corresponding VOL callback exists */
1680
0
    if (NULL == cls->attr_cls.optional)
1681
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr optional' method");
1682
1683
    /* Prepare & restore library for user callback */
1684
0
    H5_BEFORE_USER_CB(FAIL)
1685
0
        {
1686
            /* Call the corresponding VOL callback */
1687
            /* (Must return value from callback, for iterators) */
1688
0
            ret_value = (cls->attr_cls.optional)(obj, args, dxpl_id, req);
1689
0
        }
1690
0
    H5_AFTER_USER_CB(FAIL)
1691
0
    if (ret_value < 0)
1692
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback");
1693
1694
0
done:
1695
0
    FUNC_LEAVE_NOAPI(ret_value)
1696
0
} /* end H5VL__attr_optional() */
1697
1698
/*-------------------------------------------------------------------------
1699
 * Function:  H5VL_attr_optional
1700
 *
1701
 * Purpose: Optional operation specific to connectors.
1702
 *
1703
 * Return:      Success:    Non-negative
1704
 *              Failure:    Negative
1705
 *
1706
 *-------------------------------------------------------------------------
1707
 */
1708
herr_t
1709
H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
1710
0
{
1711
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
1712
0
    herr_t ret_value       = SUCCEED; /* Return value */
1713
1714
0
    FUNC_ENTER_NOAPI(FAIL)
1715
1716
    /* Set wrapper info in API context */
1717
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1718
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
1719
0
    vol_wrapper_set = true;
1720
1721
    /* Call the corresponding internal VOL routine */
1722
    /* (Must return value from callback, for iterators) */
1723
0
    if ((ret_value = H5VL__attr_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0)
1724
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback");
1725
1726
0
done:
1727
    /* Reset object wrapping info in API context */
1728
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1729
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
1730
1731
0
    FUNC_LEAVE_NOAPI(ret_value)
1732
0
} /* end H5VL_attr_optional() */
1733
1734
/*-------------------------------------------------------------------------
1735
 * Function:    H5VLattr_optional
1736
 *
1737
 * Purpose:     Performs an optional connector-specific operation on an attribute
1738
 *
1739
 * Return:      Success:    Non-negative
1740
 *              Failure:    Negative
1741
 *
1742
 *-------------------------------------------------------------------------
1743
 */
1744
herr_t
1745
H5VLattr_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id,
1746
                  void **req /*out*/)
1747
0
{
1748
0
    H5VL_connector_t *connector;           /* VOL connector */
1749
0
    herr_t            ret_value = SUCCEED; /* Return value */
1750
1751
0
    FUNC_ENTER_API_NOINIT
1752
1753
    /* Check args and get connector pointer */
1754
0
    if (NULL == obj)
1755
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
1756
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1757
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
1758
1759
    /* Call the corresponding internal VOL routine */
1760
    /* (Must return value from callback, for iterators) */
1761
0
    if ((ret_value = H5VL__attr_optional(obj, connector->cls, args, dxpl_id, req)) < 0)
1762
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback");
1763
1764
0
done:
1765
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1766
0
} /* end H5VLattr_optional() */
1767
1768
/*-------------------------------------------------------------------------
1769
 * Function:    H5VLattr_optional_op
1770
 *
1771
 * Purpose:     Performs an optional connector-specific operation on an attribute
1772
 *
1773
 * Return:      Success:    Non-negative
1774
 *              Failure:    Negative
1775
 *
1776
 *-------------------------------------------------------------------------
1777
 */
1778
herr_t
1779
H5VLattr_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id,
1780
                     H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id)
1781
0
{
1782
0
    H5VL_object_t *vol_obj   = NULL;            /* Attribute VOL object */
1783
0
    void          *token     = NULL;            /* Request token for async operation        */
1784
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1785
0
    herr_t         ret_value = SUCCEED;         /* Return value */
1786
1787
0
    FUNC_ENTER_API(FAIL)
1788
1789
    /* Set up request token pointer for asynchronous operation */
1790
0
    if (H5ES_NONE != es_id)
1791
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
1792
1793
    /* Call the common VOL connector optional routine */
1794
0
    if ((ret_value = H5VL__common_optional_op(attr_id, H5I_ATTR, H5VL__attr_optional, args, dxpl_id,
1795
0
                                              token_ptr, &vol_obj)) < 0)
1796
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback");
1797
1798
    /* If a token was created, add the token to the event set */
1799
0
    if (NULL != token)
1800
        /* clang-format off */
1801
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
1802
0
                        H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, attr_id, args, dxpl_id, es_id)) < 0)
1803
            /* clang-format on */
1804
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1805
1806
0
done:
1807
0
    FUNC_LEAVE_API(ret_value)
1808
0
} /* end H5VLattr_optional_op() */
1809
1810
/*-------------------------------------------------------------------------
1811
 * Function:    H5VL__attr_close
1812
 *
1813
 * Purpose:     Closes an attribute through the VOL
1814
 *
1815
 * Return:      Success:    Non-negative
1816
 *              Failure:    Negative
1817
 *
1818
 *-------------------------------------------------------------------------
1819
 */
1820
static herr_t
1821
H5VL__attr_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req)
1822
0
{
1823
0
    herr_t ret_value = SUCCEED; /* Return value */
1824
1825
0
    FUNC_ENTER_PACKAGE
1826
1827
    /* Check if the corresponding VOL callback exists */
1828
0
    if (NULL == cls->attr_cls.close)
1829
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr close' method");
1830
1831
    /* Prepare & restore library for user callback */
1832
0
    H5_BEFORE_USER_CB(FAIL)
1833
0
        {
1834
            /* Call the corresponding VOL callback */
1835
0
            ret_value = (cls->attr_cls.close)(obj, dxpl_id, req);
1836
0
        }
1837
0
    H5_AFTER_USER_CB(FAIL)
1838
0
    if (ret_value < 0)
1839
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "attribute close failed");
1840
1841
0
done:
1842
0
    FUNC_LEAVE_NOAPI(ret_value)
1843
0
} /* end H5VL__attr_close() */
1844
1845
/*-------------------------------------------------------------------------
1846
 * Function:    H5VL_attr_close
1847
 *
1848
 * Purpose:     Closes an attribute through the VOL
1849
 *
1850
 * Return:      Success:    Non-negative
1851
 *              Failure:    Negative
1852
 *
1853
 *-------------------------------------------------------------------------
1854
 */
1855
herr_t
1856
H5VL_attr_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req)
1857
0
{
1858
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
1859
0
    herr_t ret_value       = SUCCEED; /* Return value */
1860
1861
0
    FUNC_ENTER_NOAPI(FAIL)
1862
1863
    /* Sanity check */
1864
0
    assert(vol_obj);
1865
1866
    /* Set wrapper info in API context */
1867
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1868
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
1869
0
    vol_wrapper_set = true;
1870
1871
    /* Call the corresponding internal VOL routine */
1872
0
    if (H5VL__attr_close(vol_obj->data, vol_obj->connector->cls, dxpl_id, req) < 0)
1873
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "attribute close failed");
1874
1875
0
done:
1876
    /* Reset object wrapping info in API context */
1877
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1878
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
1879
1880
0
    FUNC_LEAVE_NOAPI(ret_value)
1881
0
} /* end H5VL_attr_close() */
1882
1883
/*-------------------------------------------------------------------------
1884
 * Function:    H5VLattr_close
1885
 *
1886
 * Purpose:     Closes an attribute
1887
 *
1888
 * Return:      Success:    Non-negative
1889
 *              Failure:    Negative
1890
 *
1891
 *-------------------------------------------------------------------------
1892
 */
1893
herr_t
1894
H5VLattr_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/)
1895
0
{
1896
0
    H5VL_connector_t *connector;           /* VOL connector */
1897
0
    herr_t            ret_value = SUCCEED; /* Return value */
1898
1899
0
    FUNC_ENTER_API_NOINIT
1900
1901
    /* Check args and get connector pointer */
1902
0
    if (NULL == obj)
1903
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
1904
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
1905
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
1906
1907
    /* Call the corresponding internal VOL routine */
1908
0
    if (H5VL__attr_close(obj, connector->cls, dxpl_id, req) < 0)
1909
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "unable to close attribute");
1910
1911
0
done:
1912
0
    FUNC_LEAVE_API_NOINIT(ret_value)
1913
0
} /* end H5VLattr_close() */
1914
1915
/*-------------------------------------------------------------------------
1916
 * Function:  H5VL__dataset_create
1917
 *
1918
 * Purpose: Creates a dataset through the VOL
1919
 *
1920
 * Return:      Success: Pointer to new dataset
1921
 *    Failure: NULL
1922
 *
1923
 *-------------------------------------------------------------------------
1924
 */
1925
static void *
1926
H5VL__dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
1927
                     const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id, hid_t dcpl_id,
1928
                     hid_t dapl_id, hid_t dxpl_id, void **req)
1929
0
{
1930
0
    void *ret_value = NULL; /* Return value */
1931
1932
0
    FUNC_ENTER_PACKAGE
1933
1934
    /* Check if the corresponding VOL callback exists */
1935
0
    if (NULL == cls->dataset_cls.create)
1936
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'dataset create' method");
1937
1938
    /* Prepare & restore library for user callback */
1939
0
    H5_BEFORE_USER_CB(NULL)
1940
0
        {
1941
            /* Call the corresponding VOL callback */
1942
0
            ret_value = (cls->dataset_cls.create)(obj, loc_params, name, lcpl_id, type_id, space_id, dcpl_id,
1943
0
                                                  dapl_id, dxpl_id, req);
1944
0
        }
1945
0
    H5_AFTER_USER_CB(NULL)
1946
0
    if (NULL == ret_value)
1947
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "dataset create failed");
1948
1949
0
done:
1950
0
    FUNC_LEAVE_NOAPI(ret_value)
1951
0
} /* end H5VL__dataset_create() */
1952
1953
/*-------------------------------------------------------------------------
1954
 * Function:  H5VL_dataset_create
1955
 *
1956
 * Purpose: Creates a dataset through the VOL
1957
 *
1958
 * Return:      Success: Pointer to new dataset
1959
 *    Failure: NULL
1960
 *
1961
 *-------------------------------------------------------------------------
1962
 */
1963
void *
1964
H5VL_dataset_create(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
1965
                    hid_t lcpl_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id,
1966
                    void **req)
1967
0
{
1968
0
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
1969
0
    void *ret_value       = NULL;  /* Return value */
1970
1971
0
    FUNC_ENTER_NOAPI(NULL)
1972
1973
    /* Set wrapper info in API context */
1974
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
1975
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
1976
0
    vol_wrapper_set = true;
1977
1978
    /* Call the corresponding internal VOL routine */
1979
0
    if (NULL ==
1980
0
        (ret_value = H5VL__dataset_create(vol_obj->data, loc_params, vol_obj->connector->cls, name, lcpl_id,
1981
0
                                          type_id, space_id, dcpl_id, dapl_id, dxpl_id, req)))
1982
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "dataset create failed");
1983
1984
0
done:
1985
    /* Reset object wrapping info in API context */
1986
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
1987
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
1988
1989
0
    FUNC_LEAVE_NOAPI(ret_value)
1990
0
} /* end H5VL_dataset_create() */
1991
1992
/*-------------------------------------------------------------------------
1993
 * Function:    H5VLdataset_create
1994
 *
1995
 * Purpose:     Creates a dataset
1996
 *
1997
 * Return:      Success:    Pointer to the new dataset
1998
 *              Failure:    NULL
1999
 *
2000
 *-------------------------------------------------------------------------
2001
 */
2002
void *
2003
H5VLdataset_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
2004
                   hid_t lcpl_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id,
2005
                   void **req /*out*/)
2006
0
{
2007
0
    H5VL_connector_t *connector;        /* VOL connector */
2008
0
    void             *ret_value = NULL; /* Return value */
2009
2010
0
    FUNC_ENTER_API_NOINIT
2011
2012
    /* Check args and get connector pointer */
2013
0
    if (NULL == obj)
2014
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
2015
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2016
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
2017
2018
    /* Call the corresponding internal VOL routine */
2019
0
    if (NULL == (ret_value = H5VL__dataset_create(obj, loc_params, connector->cls, name, lcpl_id, type_id,
2020
0
                                                  space_id, dcpl_id, dapl_id, dxpl_id, req)))
2021
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "unable to create dataset");
2022
2023
0
done:
2024
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2025
0
} /* end H5VLdataset_create() */
2026
2027
/*-------------------------------------------------------------------------
2028
 * Function:  H5VL__dataset_open
2029
 *
2030
 * Purpose: Opens a dataset through the VOL
2031
 *
2032
 * Return:      Success: Pointer to dataset
2033
 *    Failure: NULL
2034
 *
2035
 *-------------------------------------------------------------------------
2036
 */
2037
static void *
2038
H5VL__dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name,
2039
                   hid_t dapl_id, hid_t dxpl_id, void **req)
2040
673
{
2041
673
    void *ret_value = NULL; /* Return value */
2042
2043
673
    FUNC_ENTER_PACKAGE
2044
2045
    /* Check if the corresponding VOL callback exists */
2046
673
    if (NULL == cls->dataset_cls.open)
2047
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'dataset open' method");
2048
2049
    /* Prepare & restore library for user callback */
2050
673
    H5_BEFORE_USER_CB(NULL)
2051
673
        {
2052
            /* Call the corresponding VOL callback */
2053
673
            ret_value = (cls->dataset_cls.open)(obj, loc_params, name, dapl_id, dxpl_id, req);
2054
673
        }
2055
673
    H5_AFTER_USER_CB(NULL)
2056
673
    if (NULL == ret_value)
2057
605
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "dataset open failed");
2058
2059
673
done:
2060
673
    FUNC_LEAVE_NOAPI(ret_value)
2061
673
} /* end H5VL__dataset_open() */
2062
2063
/*-------------------------------------------------------------------------
2064
 * Function:  H5VL_dataset_open
2065
 *
2066
 * Purpose: Opens a dataset through the VOL
2067
 *
2068
 * Return:      Success: Pointer to dataset
2069
 *    Failure: NULL
2070
 *
2071
 *-------------------------------------------------------------------------
2072
 */
2073
void *
2074
H5VL_dataset_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
2075
                  hid_t dapl_id, hid_t dxpl_id, void **req)
2076
673
{
2077
673
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
2078
673
    void *ret_value       = NULL;  /* Return value */
2079
2080
673
    FUNC_ENTER_NOAPI(NULL)
2081
2082
    /* Set wrapper info in API context */
2083
673
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
2084
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
2085
673
    vol_wrapper_set = true;
2086
2087
    /* Call the corresponding internal VOL routine */
2088
673
    if (NULL == (ret_value = H5VL__dataset_open(vol_obj->data, loc_params, vol_obj->connector->cls, name,
2089
673
                                                dapl_id, dxpl_id, req)))
2090
605
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "dataset open failed");
2091
2092
673
done:
2093
    /* Reset object wrapping info in API context */
2094
673
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2095
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
2096
2097
673
    FUNC_LEAVE_NOAPI(ret_value)
2098
673
} /* end H5VL_dataset_open() */
2099
2100
/*-------------------------------------------------------------------------
2101
 * Function:    H5VLdataset_open
2102
 *
2103
 * Purpose:     Opens a dataset
2104
 *
2105
 * Return:      Success:    Pointer to the new dataset
2106
 *              Failure:    NULL
2107
 *
2108
 *-------------------------------------------------------------------------
2109
 */
2110
void *
2111
H5VLdataset_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
2112
                 hid_t dapl_id, hid_t dxpl_id, void **req /*out*/)
2113
0
{
2114
0
    H5VL_connector_t *connector;        /* VOL connector */
2115
0
    void             *ret_value = NULL; /* Return value */
2116
2117
0
    FUNC_ENTER_API_NOINIT
2118
2119
    /* Check args and get connector pointer */
2120
0
    if (NULL == obj)
2121
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
2122
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2123
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
2124
2125
    /* Call the corresponding internal VOL routine */
2126
0
    if (NULL ==
2127
0
        (ret_value = H5VL__dataset_open(obj, loc_params, connector->cls, name, dapl_id, dxpl_id, req)))
2128
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "unable to open dataset");
2129
2130
0
done:
2131
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2132
0
} /* end H5VLdataset_open() */
2133
2134
/*-------------------------------------------------------------------------
2135
 * Function:    H5VL__dataset_read
2136
 *
2137
 * Purpose:     Reads data from dataset through the VOL
2138
 *
2139
 * Return:      Success:    Non-negative
2140
 *              Failure:    Negative
2141
 *
2142
 *-------------------------------------------------------------------------
2143
 */
2144
static herr_t
2145
H5VL__dataset_read(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
2146
                   hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req)
2147
0
{
2148
0
    herr_t ret_value = SUCCEED; /* Return value */
2149
2150
0
    FUNC_ENTER_PACKAGE
2151
2152
    /* Check if the corresponding VOL callback exists */
2153
0
    if (NULL == cls->dataset_cls.read)
2154
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset read' method");
2155
2156
    /* Prepare & restore library for user callback */
2157
0
    H5_BEFORE_USER_CB(FAIL)
2158
0
        {
2159
            /* Call the corresponding VOL callback */
2160
0
            ret_value = (cls->dataset_cls.read)(count, obj, mem_type_id, mem_space_id, file_space_id, dxpl_id,
2161
0
                                                buf, req);
2162
0
        }
2163
0
    H5_AFTER_USER_CB(FAIL)
2164
0
    if (ret_value < 0)
2165
0
        HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "dataset read failed");
2166
2167
0
done:
2168
0
    FUNC_LEAVE_NOAPI(ret_value)
2169
0
} /* end H5VL__dataset_read() */
2170
2171
/*-------------------------------------------------------------------------
2172
 * Function:    H5VL_dataset_read
2173
 *
2174
 * Purpose:     Reads data from dataset through the VOL.  This is like
2175
 *              H5VL_dataset_read, but takes an array of void * for the
2176
 *              objects and a connector pointer instead of an array of
2177
 *              H5VL_object_t.  This allows us to avoid allocating and
2178
 *              copying an extra array (of H5VL_object_ts).
2179
 *
2180
 * Return:      Success:    Non-negative
2181
 *              Failure:    Negative
2182
 *
2183
 *-------------------------------------------------------------------------
2184
 */
2185
herr_t
2186
H5VL_dataset_read(size_t count, void *obj[], H5VL_connector_t *connector, hid_t mem_type_id[],
2187
                  hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req)
2188
0
{
2189
0
    bool          vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
2190
0
    H5VL_object_t tmp_vol_obj;             /* Temporary VOL object for setting VOL wrapper */
2191
0
    herr_t        ret_value = SUCCEED;     /* Return value */
2192
2193
0
    FUNC_ENTER_NOAPI(FAIL)
2194
2195
0
    assert(obj);
2196
0
    assert(connector);
2197
2198
    /* Set wrapper info in API context */
2199
0
    tmp_vol_obj.data      = obj[0];
2200
0
    tmp_vol_obj.connector = connector;
2201
0
    tmp_vol_obj.rc        = 1;
2202
0
    if (H5VL_set_vol_wrapper(&tmp_vol_obj) < 0)
2203
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
2204
0
    vol_wrapper_set = true;
2205
2206
    /* Call the corresponding internal VOL routine */
2207
0
    if (H5VL__dataset_read(count, obj, connector->cls, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
2208
0
                           req) < 0)
2209
0
        HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "dataset read failed");
2210
2211
0
done:
2212
    /* Reset object wrapping info in API context */
2213
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2214
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
2215
2216
0
    FUNC_LEAVE_NOAPI(ret_value)
2217
0
} /* end H5VL_dataset_read() */
2218
2219
/*-------------------------------------------------------------------------
2220
 * Function:    H5VLdataset_read
2221
 *
2222
 * Purpose:     Reads data from a dataset
2223
 *
2224
 * Return:      Success:    Non-negative
2225
 *              Failure:    Negative
2226
 *
2227
 *-------------------------------------------------------------------------
2228
 */
2229
herr_t
2230
H5VLdataset_read(size_t count, void *obj[], hid_t connector_id, hid_t mem_type_id[], hid_t mem_space_id[],
2231
                 hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req /*out*/)
2232
0
{
2233
0
    H5VL_connector_t *connector;           /* VOL connector */
2234
0
    size_t            i;                   /* Local index variable */
2235
0
    herr_t            ret_value = SUCCEED; /* Return value */
2236
2237
0
    FUNC_ENTER_API_NOINIT
2238
2239
    /* Check args and get connector pointer */
2240
0
    if (NULL == obj)
2241
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "obj array not provided");
2242
0
    for (i = 1; i < count; i++)
2243
0
        if (NULL == obj[i])
2244
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
2245
0
    if (NULL == mem_type_id)
2246
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_type_id array not provided");
2247
0
    if (NULL == mem_space_id)
2248
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_space_id array not provided");
2249
0
    if (NULL == file_space_id)
2250
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_space_id array not provided");
2251
0
    if (NULL == buf)
2252
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf array not provided");
2253
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2254
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
2255
2256
    /* Call the corresponding internal VOL routine */
2257
0
    if (H5VL__dataset_read(count, obj, connector->cls, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
2258
0
                           req) < 0)
2259
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to read dataset");
2260
2261
0
done:
2262
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2263
0
} /* end H5VLdataset_read() */
2264
2265
/*-------------------------------------------------------------------------
2266
 * Function:    H5VL__dataset_write
2267
 *
2268
 * Purpose:     Writes data from dataset through the VOL
2269
 *
2270
 * Return:      Success:    Non-negative
2271
 *              Failure:    Negative
2272
 *
2273
 *-------------------------------------------------------------------------
2274
 */
2275
static herr_t
2276
H5VL__dataset_write(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
2277
                    hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req)
2278
0
{
2279
0
    herr_t ret_value = SUCCEED; /* Return value */
2280
2281
0
    FUNC_ENTER_PACKAGE
2282
2283
    /* Check if the corresponding VOL callback exists */
2284
0
    if (NULL == cls->dataset_cls.write)
2285
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset write' method");
2286
2287
    /* Prepare & restore library for user callback */
2288
0
    H5_BEFORE_USER_CB(FAIL)
2289
0
        {
2290
            /* Call the corresponding VOL callback */
2291
0
            ret_value = (cls->dataset_cls.write)(count, obj, mem_type_id, mem_space_id, file_space_id,
2292
0
                                                 dxpl_id, buf, req);
2293
0
        }
2294
0
    H5_AFTER_USER_CB(FAIL)
2295
0
    if (ret_value < 0)
2296
0
        HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "dataset write failed");
2297
2298
0
done:
2299
0
    FUNC_LEAVE_NOAPI(ret_value)
2300
0
} /* end H5VL__dataset_write() */
2301
2302
/*-------------------------------------------------------------------------
2303
 * Function:    H5VL_dataset_write
2304
 *
2305
 * Purpose:     Writes data from dataset through the VOL.  This is like
2306
 *              H5VL_dataset_write, but takes an array of void * for the
2307
 *              objects and a connector pointer instead of an array of
2308
 *              H5VL_object_t.  This allows us to avoid allocating and
2309
 *              copying an extra array (of H5VL_object_ts).
2310
 *
2311
 * Return:      Success:    Non-negative
2312
 *              Failure:    Negative
2313
 *
2314
 *-------------------------------------------------------------------------
2315
 */
2316
herr_t
2317
H5VL_dataset_write(size_t count, void *obj[], H5VL_connector_t *connector, hid_t mem_type_id[],
2318
                   hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req)
2319
0
{
2320
0
    bool          vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
2321
0
    H5VL_object_t tmp_vol_obj;             /* Temporary VOL object for setting VOL wrapper */
2322
0
    herr_t        ret_value = SUCCEED;     /* Return value */
2323
2324
0
    FUNC_ENTER_NOAPI(FAIL)
2325
2326
0
    assert(obj);
2327
0
    assert(connector);
2328
2329
    /* Set wrapper info in API context */
2330
0
    tmp_vol_obj.data      = obj[0];
2331
0
    tmp_vol_obj.connector = connector;
2332
0
    tmp_vol_obj.rc        = 1;
2333
0
    if (H5VL_set_vol_wrapper(&tmp_vol_obj) < 0)
2334
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
2335
0
    vol_wrapper_set = true;
2336
2337
    /* Call the corresponding internal VOL routine */
2338
0
    if (H5VL__dataset_write(count, obj, connector->cls, mem_type_id, mem_space_id, file_space_id, dxpl_id,
2339
0
                            buf, req) < 0)
2340
0
        HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "dataset write failed");
2341
2342
0
done:
2343
    /* Reset object wrapping info in API context */
2344
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2345
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
2346
2347
0
    FUNC_LEAVE_NOAPI(ret_value)
2348
0
} /* end H5VL_dataset_write() */
2349
2350
/*-------------------------------------------------------------------------
2351
 * Function:    H5VLdataset_write
2352
 *
2353
 * Purpose:     Writes data to a dataset
2354
 *
2355
 * Return:      Success:    Non-negative
2356
 *              Failure:    Negative
2357
 *
2358
 *-------------------------------------------------------------------------
2359
 */
2360
herr_t
2361
H5VLdataset_write(size_t count, void *obj[], hid_t connector_id, hid_t mem_type_id[], hid_t mem_space_id[],
2362
                  hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req /*out*/)
2363
0
{
2364
0
    H5VL_connector_t *connector;           /* VOL connector */
2365
0
    size_t            i;                   /* Local index variable */
2366
0
    herr_t            ret_value = SUCCEED; /* Return value */
2367
2368
0
    FUNC_ENTER_API_NOINIT
2369
2370
    /* Check args and get connector pointer */
2371
0
    if (NULL == obj)
2372
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "obj array not provided");
2373
0
    for (i = 1; i < count; i++)
2374
0
        if (NULL == obj[i])
2375
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
2376
0
    if (NULL == mem_type_id)
2377
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_type_id array not provided");
2378
0
    if (NULL == mem_space_id)
2379
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_space_id array not provided");
2380
0
    if (NULL == file_space_id)
2381
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_space_id array not provided");
2382
0
    if (NULL == buf)
2383
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf array not provided");
2384
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2385
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
2386
2387
    /* Call the corresponding internal VOL routine */
2388
0
    if (H5VL__dataset_write(count, obj, connector->cls, mem_type_id, mem_space_id, file_space_id, dxpl_id,
2389
0
                            buf, req) < 0)
2390
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to write dataset");
2391
2392
0
done:
2393
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2394
0
} /* end H5VLdataset_write() */
2395
2396
/*-------------------------------------------------------------------------
2397
 * Function:  H5VL__dataset_get
2398
 *
2399
 * Purpose: Get specific information about the dataset through the VOL
2400
 *
2401
 * Return:      Success:    Non-negative
2402
 *              Failure:    Negative
2403
 *
2404
 *-------------------------------------------------------------------------
2405
 */
2406
static herr_t
2407
H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_args_t *args, hid_t dxpl_id,
2408
                  void **req)
2409
0
{
2410
0
    herr_t ret_value = SUCCEED; /* Return value */
2411
2412
0
    FUNC_ENTER_PACKAGE
2413
2414
    /* Check if the corresponding VOL callback exists */
2415
0
    if (NULL == cls->dataset_cls.get)
2416
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset get' method");
2417
2418
    /* Prepare & restore library for user callback */
2419
0
    H5_BEFORE_USER_CB(FAIL)
2420
0
        {
2421
            /* Call the corresponding VOL callback */
2422
0
            ret_value = (cls->dataset_cls.get)(obj, args, dxpl_id, req);
2423
0
        }
2424
0
    H5_AFTER_USER_CB(FAIL)
2425
0
    if (ret_value < 0)
2426
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "dataset get failed");
2427
2428
0
done:
2429
0
    FUNC_LEAVE_NOAPI(ret_value)
2430
0
} /* end H5VL__dataset_get() */
2431
2432
/*-------------------------------------------------------------------------
2433
 * Function:  H5VL_dataset_get
2434
 *
2435
 * Purpose: Get specific information about the dataset through the VOL
2436
 *
2437
 * Return:      Success:    Non-negative
2438
 *              Failure:    Negative
2439
 *
2440
 *-------------------------------------------------------------------------
2441
 */
2442
herr_t
2443
H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req)
2444
0
{
2445
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
2446
0
    herr_t ret_value       = SUCCEED; /* Return value */
2447
2448
0
    FUNC_ENTER_NOAPI(FAIL)
2449
2450
    /* Set wrapper info in API context */
2451
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
2452
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
2453
0
    vol_wrapper_set = true;
2454
2455
    /* Call the corresponding internal VOL routine */
2456
0
    if (H5VL__dataset_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
2457
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "dataset get failed");
2458
2459
0
done:
2460
    /* Reset object wrapping info in API context */
2461
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2462
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
2463
2464
0
    FUNC_LEAVE_NOAPI(ret_value)
2465
0
} /* end H5VL_dataset_get() */
2466
2467
/*-------------------------------------------------------------------------
2468
 * Function:    H5VLdataset_get
2469
 *
2470
 * Purpose:     Gets information about a dataset
2471
 *
2472
 * Return:      Success:    Non-negative
2473
 *              Failure:    Negative
2474
 *
2475
 *-------------------------------------------------------------------------
2476
 */
2477
herr_t
2478
H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_args_t *args, hid_t dxpl_id,
2479
                void **req /*out*/)
2480
0
{
2481
0
    H5VL_connector_t *connector;           /* VOL connector */
2482
0
    herr_t            ret_value = SUCCEED; /* Return value */
2483
2484
0
    FUNC_ENTER_API_NOINIT
2485
2486
    /* Check args and get connector pointer */
2487
0
    if (NULL == obj)
2488
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
2489
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2490
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
2491
2492
    /* Call the corresponding internal VOL routine */
2493
0
    if (H5VL__dataset_get(obj, connector->cls, args, dxpl_id, req) < 0)
2494
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute dataset get callback");
2495
2496
0
done:
2497
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2498
0
} /* end H5VLdataset_get() */
2499
2500
/*-------------------------------------------------------------------------
2501
 * Function:  H5VL__dataset_specific
2502
 *
2503
 * Purpose: Specific operation on datasets through the VOL
2504
 *
2505
 * Return:      Success:    Non-negative
2506
 *              Failure:    Negative
2507
 *
2508
 *-------------------------------------------------------------------------
2509
 */
2510
static herr_t
2511
H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_args_t *args, hid_t dxpl_id,
2512
                       void **req)
2513
0
{
2514
0
    herr_t ret_value = SUCCEED; /* Return value */
2515
2516
0
    FUNC_ENTER_PACKAGE
2517
2518
    /* Check if the corresponding VOL callback exists */
2519
0
    if (NULL == cls->dataset_cls.specific)
2520
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset specific' method");
2521
2522
    /* Prepare & restore library for user callback */
2523
0
    H5_BEFORE_USER_CB(FAIL)
2524
0
        {
2525
            /* Call the corresponding VOL callback */
2526
0
            ret_value = (cls->dataset_cls.specific)(obj, args, dxpl_id, req);
2527
0
        }
2528
0
    H5_AFTER_USER_CB(FAIL)
2529
0
    if (ret_value < 0)
2530
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback");
2531
2532
0
done:
2533
0
    FUNC_LEAVE_NOAPI(ret_value)
2534
0
} /* end H5VL__dataset_specific() */
2535
2536
/*-------------------------------------------------------------------------
2537
 * Function:  H5VL_dataset_specific
2538
 *
2539
 * Purpose: Specific operation on datasets through the VOL
2540
 *
2541
 * Return:      Success:    Non-negative
2542
 *              Failure:    Negative
2543
 *
2544
 *-------------------------------------------------------------------------
2545
 */
2546
herr_t
2547
H5VL_dataset_specific(const H5VL_object_t *vol_obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id,
2548
                      void **req)
2549
0
{
2550
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
2551
0
    herr_t ret_value       = SUCCEED; /* Return value */
2552
2553
0
    FUNC_ENTER_NOAPI(FAIL)
2554
2555
    /* Set wrapper info in API context */
2556
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
2557
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
2558
0
    vol_wrapper_set = true;
2559
2560
    /* Call the corresponding internal VOL routine */
2561
0
    if (H5VL__dataset_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
2562
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback");
2563
2564
0
done:
2565
    /* Reset object wrapping info in API context */
2566
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2567
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
2568
2569
0
    FUNC_LEAVE_NOAPI(ret_value)
2570
0
} /* end H5VL_dataset_specific() */
2571
2572
/*-------------------------------------------------------------------------
2573
 * Function:    H5VLdataset_specific
2574
 *
2575
 * Purpose:     Performs a connector-specific operation on a dataset
2576
 *
2577
 * Return:      Success:    Non-negative
2578
 *              Failure:    Negative
2579
 *
2580
 *-------------------------------------------------------------------------
2581
 */
2582
herr_t
2583
H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_args_t *args, hid_t dxpl_id,
2584
                     void **req /*out*/)
2585
0
{
2586
0
    H5VL_connector_t *connector;           /* VOL connector */
2587
0
    herr_t            ret_value = SUCCEED; /* Return value */
2588
2589
0
    FUNC_ENTER_API_NOINIT
2590
2591
    /* Check args and get connector pointer */
2592
0
    if (NULL == obj)
2593
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
2594
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2595
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
2596
2597
    /* Call the corresponding internal VOL routine */
2598
0
    if (H5VL__dataset_specific(obj, connector->cls, args, dxpl_id, req) < 0)
2599
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback");
2600
2601
0
done:
2602
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2603
0
} /* end H5VLdataset_specific() */
2604
2605
/*-------------------------------------------------------------------------
2606
 * Function:  H5VL__dataset_optional
2607
 *
2608
 * Purpose: Optional operation specific to connectors.
2609
 *
2610
 * Return:      Success:    Non-negative
2611
 *              Failure:    Negative
2612
 *
2613
 *-------------------------------------------------------------------------
2614
 */
2615
static herr_t
2616
H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id,
2617
                       void **req)
2618
0
{
2619
0
    herr_t ret_value = SUCCEED; /* Return value */
2620
2621
0
    FUNC_ENTER_PACKAGE
2622
2623
    /* Check if the corresponding VOL callback exists */
2624
0
    if (NULL == cls->dataset_cls.optional)
2625
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset optional' method");
2626
2627
    /* Prepare & restore library for user callback */
2628
0
    H5_BEFORE_USER_CB(FAIL)
2629
0
        {
2630
            /* Call the corresponding VOL callback */
2631
0
            ret_value = (cls->dataset_cls.optional)(obj, args, dxpl_id, req);
2632
0
        }
2633
0
    H5_AFTER_USER_CB(FAIL)
2634
0
    if (ret_value < 0)
2635
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback");
2636
2637
0
done:
2638
0
    FUNC_LEAVE_NOAPI(ret_value)
2639
0
} /* end H5VL__dataset_optional() */
2640
2641
/*-------------------------------------------------------------------------
2642
 * Function:  H5VL_dataset_optional
2643
 *
2644
 * Purpose: Optional operation specific to connectors.
2645
 *
2646
 * Return:      Success:    Non-negative
2647
 *              Failure:    Negative
2648
 *
2649
 *-------------------------------------------------------------------------
2650
 */
2651
herr_t
2652
H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
2653
0
{
2654
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
2655
0
    herr_t ret_value       = SUCCEED; /* Return value */
2656
2657
0
    FUNC_ENTER_NOAPI(FAIL)
2658
2659
    /* Set wrapper info in API context */
2660
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
2661
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
2662
0
    vol_wrapper_set = true;
2663
2664
    /* Call the corresponding internal VOL routine */
2665
0
    if (H5VL__dataset_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
2666
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback");
2667
2668
0
done:
2669
    /* Reset object wrapping info in API context */
2670
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2671
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
2672
2673
0
    FUNC_LEAVE_NOAPI(ret_value)
2674
0
} /* end H5VL_dataset_optional() */
2675
2676
/*-------------------------------------------------------------------------
2677
 * Function:    H5VLdataset_optional
2678
 *
2679
 * Purpose:     Performs an optional connector-specific operation on a dataset
2680
 *
2681
 * Return:      Success:    Non-negative
2682
 *              Failure:    Negative
2683
 *
2684
 *-------------------------------------------------------------------------
2685
 */
2686
herr_t
2687
H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id,
2688
                     void **req /*out*/)
2689
0
{
2690
0
    H5VL_connector_t *connector;           /* VOL connector */
2691
0
    herr_t            ret_value = SUCCEED; /* Return value */
2692
2693
0
    FUNC_ENTER_API_NOINIT
2694
2695
    /* Check args and get connector pointer */
2696
0
    if (NULL == obj)
2697
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
2698
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2699
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
2700
2701
    /* Call the corresponding internal VOL routine */
2702
0
    if (H5VL__dataset_optional(obj, connector->cls, args, dxpl_id, req) < 0)
2703
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback");
2704
2705
0
done:
2706
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2707
0
} /* end H5VLdataset_optional() */
2708
2709
/*-------------------------------------------------------------------------
2710
 * Function:    H5VLdataset_optional_op
2711
 *
2712
 * Purpose:     Performs an optional connector-specific operation on a dataset
2713
 *
2714
 * Return:      Success:    Non-negative
2715
 *              Failure:    Negative
2716
 *
2717
 *-------------------------------------------------------------------------
2718
 */
2719
herr_t
2720
H5VLdataset_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id,
2721
                        H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id)
2722
0
{
2723
0
    H5VL_object_t *vol_obj   = NULL;            /* Dataset VOL object */
2724
0
    void          *token     = NULL;            /* Request token for async operation        */
2725
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
2726
0
    herr_t         ret_value = SUCCEED;         /* Return value */
2727
2728
0
    FUNC_ENTER_API(FAIL)
2729
2730
    /* Set up request token pointer for asynchronous operation */
2731
0
    if (H5ES_NONE != es_id)
2732
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
2733
2734
    /* Call the corresponding internal VOL routine */
2735
0
    if (H5VL__common_optional_op(dset_id, H5I_DATASET, H5VL__dataset_optional, args, dxpl_id, token_ptr,
2736
0
                                 &vol_obj) < 0)
2737
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback");
2738
2739
    /* If a token was created, add the token to the event set */
2740
0
    if (NULL != token)
2741
        /* clang-format off */
2742
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
2743
0
                        H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, dset_id, args, dxpl_id, es_id)) < 0)
2744
            /* clang-format on */
2745
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set");
2746
2747
0
done:
2748
0
    FUNC_LEAVE_API(ret_value)
2749
0
} /* end H5VLdataset_optional_op() */
2750
2751
/*-------------------------------------------------------------------------
2752
 * Function:    H5VL__dataset_close
2753
 *
2754
 * Purpose:     Closes a dataset through the VOL
2755
 *
2756
 * Return:      Success:    Non-negative
2757
 *              Failure:    Negative
2758
 *
2759
 *-------------------------------------------------------------------------
2760
 */
2761
static herr_t
2762
H5VL__dataset_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req)
2763
68
{
2764
68
    herr_t ret_value = SUCCEED; /* Return value */
2765
2766
68
    FUNC_ENTER_PACKAGE
2767
2768
    /* Sanity check */
2769
68
    assert(obj);
2770
68
    assert(cls);
2771
2772
    /* Check if the corresponding VOL callback exists */
2773
68
    if (NULL == cls->dataset_cls.close)
2774
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset close' method");
2775
2776
    /* Prepare & restore library for user callback */
2777
68
    H5_BEFORE_USER_CB(FAIL)
2778
68
        {
2779
            /* Call the corresponding VOL callback */
2780
68
            ret_value = (cls->dataset_cls.close)(obj, dxpl_id, req);
2781
68
        }
2782
68
    H5_AFTER_USER_CB(FAIL)
2783
68
    if (ret_value < 0)
2784
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "dataset close failed");
2785
2786
68
done:
2787
68
    FUNC_LEAVE_NOAPI(ret_value)
2788
68
} /* end H5VL__dataset_close() */
2789
2790
/*-------------------------------------------------------------------------
2791
 * Function:    H5VL_dataset_close
2792
 *
2793
 * Purpose:     Closes a dataset through the VOL
2794
 *
2795
 * Return:      Success:    Non-negative
2796
 *              Failure:    Negative
2797
 *
2798
 *-------------------------------------------------------------------------
2799
 */
2800
herr_t
2801
H5VL_dataset_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req)
2802
68
{
2803
68
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
2804
68
    herr_t ret_value       = SUCCEED; /* Return value */
2805
2806
68
    FUNC_ENTER_NOAPI(FAIL)
2807
2808
    /* Sanity check */
2809
68
    assert(vol_obj);
2810
68
    assert(vol_obj->data);
2811
68
    assert(vol_obj->connector);
2812
68
    assert(vol_obj->connector->cls);
2813
2814
    /* Set wrapper info in API context */
2815
68
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
2816
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
2817
68
    vol_wrapper_set = true;
2818
2819
    /* Call the corresponding internal VOL routine */
2820
68
    if (H5VL__dataset_close(vol_obj->data, vol_obj->connector->cls, dxpl_id, req) < 0)
2821
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "dataset close failed");
2822
2823
68
done:
2824
    /* Reset object wrapping info in API context */
2825
68
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2826
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
2827
2828
68
    FUNC_LEAVE_NOAPI(ret_value)
2829
68
} /* end H5VL_dataset_close() */
2830
2831
/*-------------------------------------------------------------------------
2832
 * Function:    H5VLdataset_close
2833
 *
2834
 * Purpose:     Closes a dataset
2835
 *
2836
 * Return:      Success:    Non-negative
2837
 *              Failure:    Negative
2838
 *
2839
 *-------------------------------------------------------------------------
2840
 */
2841
herr_t
2842
H5VLdataset_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/)
2843
0
{
2844
0
    H5VL_connector_t *connector;           /* VOL connector */
2845
0
    herr_t            ret_value = SUCCEED; /* Return value */
2846
2847
0
    FUNC_ENTER_API_NOINIT
2848
2849
    /* Check args and get connector pointer */
2850
0
    if (NULL == obj)
2851
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
2852
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2853
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
2854
2855
    /* Call the corresponding internal VOL routine */
2856
0
    if (H5VL__dataset_close(obj, connector->cls, dxpl_id, req) < 0)
2857
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataset");
2858
2859
0
done:
2860
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2861
0
} /* end H5VLdataset_close() */
2862
2863
/*-------------------------------------------------------------------------
2864
 * Function:  H5VL__datatype_commit
2865
 *
2866
 * Purpose: Commits a datatype to the file through the VOL
2867
 *
2868
 * Return:      Success:    Pointer to the new datatype
2869
 *              Failure:    NULL
2870
 *
2871
 *-------------------------------------------------------------------------
2872
 */
2873
static void *
2874
H5VL__datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
2875
                      const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id,
2876
                      hid_t dxpl_id, void **req)
2877
0
{
2878
0
    void *ret_value = NULL; /* Return value */
2879
2880
0
    FUNC_ENTER_PACKAGE
2881
2882
    /* Check if the corresponding VOL callback exists */
2883
0
    if (NULL == cls->datatype_cls.commit)
2884
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'datatype commit' method");
2885
2886
    /* Prepare & restore library for user callback */
2887
0
    H5_BEFORE_USER_CB(NULL)
2888
0
        {
2889
            /* Call the corresponding VOL callback */
2890
0
            ret_value = (cls->datatype_cls.commit)(obj, loc_params, name, type_id, lcpl_id, tcpl_id, tapl_id,
2891
0
                                                   dxpl_id, req);
2892
0
        }
2893
0
    H5_AFTER_USER_CB(NULL)
2894
0
    if (NULL == ret_value)
2895
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "datatype commit failed");
2896
2897
0
done:
2898
0
    FUNC_LEAVE_NOAPI(ret_value)
2899
0
} /* end H5VL__datatype_commit() */
2900
2901
/*-------------------------------------------------------------------------
2902
 * Function:  H5VL_datatype_commit
2903
 *
2904
 * Purpose: Commits a datatype to the file through the VOL
2905
 *
2906
 * Return:      Success:    Pointer to the new datatype
2907
 *              Failure:    NULL
2908
 *
2909
 *-------------------------------------------------------------------------
2910
 */
2911
void *
2912
H5VL_datatype_commit(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
2913
                     hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req)
2914
0
{
2915
0
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
2916
0
    void *ret_value       = NULL;  /* Return value */
2917
2918
0
    FUNC_ENTER_NOAPI(NULL)
2919
2920
    /* Set wrapper info in API context */
2921
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
2922
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
2923
0
    vol_wrapper_set = true;
2924
2925
    /* Call the corresponding internal VOL routine */
2926
0
    if (NULL == (ret_value = H5VL__datatype_commit(vol_obj->data, loc_params, vol_obj->connector->cls, name,
2927
0
                                                   type_id, lcpl_id, tcpl_id, tapl_id, dxpl_id, req)))
2928
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "datatype commit failed");
2929
2930
0
done:
2931
    /* Reset object wrapping info in API context */
2932
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
2933
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
2934
2935
0
    FUNC_LEAVE_NOAPI(ret_value)
2936
0
} /* end H5VL_datatype_commit() */
2937
2938
/*-------------------------------------------------------------------------
2939
 * Function:    H5VLdatatype_commit
2940
 *
2941
 * Purpose:     Commits a datatype to the file
2942
 *
2943
 * Return:      Success:    Pointer to the new datatype
2944
 *              Failure:    NULL
2945
 *
2946
 *-------------------------------------------------------------------------
2947
 */
2948
void *
2949
H5VLdatatype_commit(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
2950
                    hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id,
2951
                    void **req /*out*/)
2952
0
{
2953
0
    H5VL_connector_t *connector;        /* VOL connector */
2954
0
    void             *ret_value = NULL; /* Return value */
2955
2956
0
    FUNC_ENTER_API_NOINIT
2957
2958
    /* Check args and get connector pointer */
2959
0
    if (NULL == obj)
2960
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
2961
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
2962
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
2963
2964
    /* Call the corresponding internal VOL routine */
2965
0
    if (NULL == (ret_value = H5VL__datatype_commit(obj, loc_params, connector->cls, name, type_id, lcpl_id,
2966
0
                                                   tcpl_id, tapl_id, dxpl_id, req)))
2967
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "unable to commit datatype");
2968
2969
0
done:
2970
0
    FUNC_LEAVE_API_NOINIT(ret_value)
2971
0
} /* end H5VLdatatype_commit() */
2972
2973
/*-------------------------------------------------------------------------
2974
 * Function:  H5VL__datatype_open
2975
 *
2976
 * Purpose: Opens a named datatype through the VOL
2977
 *
2978
 * Return:      Success:    Pointer to the datatype
2979
 *              Failure:    NULL
2980
 *
2981
 *-------------------------------------------------------------------------
2982
 */
2983
static void *
2984
H5VL__datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name,
2985
                    hid_t tapl_id, hid_t dxpl_id, void **req)
2986
0
{
2987
0
    void *ret_value = NULL; /* Return value */
2988
2989
0
    FUNC_ENTER_PACKAGE
2990
2991
    /* Check if the corresponding VOL callback exists */
2992
0
    if (NULL == cls->datatype_cls.open)
2993
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "no datatype open callback");
2994
2995
    /* Prepare & restore library for user callback */
2996
0
    H5_BEFORE_USER_CB(NULL)
2997
0
        {
2998
            /* Call the corresponding VOL callback */
2999
0
            ret_value = (cls->datatype_cls.open)(obj, loc_params, name, tapl_id, dxpl_id, req);
3000
0
        }
3001
0
    H5_AFTER_USER_CB(NULL)
3002
0
    if (NULL == ret_value)
3003
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "datatype open failed");
3004
3005
0
done:
3006
0
    FUNC_LEAVE_NOAPI(ret_value)
3007
0
} /* end H5VL__datatype_open() */
3008
3009
/*-------------------------------------------------------------------------
3010
 * Function:  H5VL_datatype_open
3011
 *
3012
 * Purpose: Opens a named datatype through the VOL
3013
 *
3014
 * Return:      Success:    Pointer to the datatype
3015
 *              Failure:    NULL
3016
 *
3017
 *-------------------------------------------------------------------------
3018
 */
3019
void *
3020
H5VL_datatype_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
3021
                   hid_t tapl_id, hid_t dxpl_id, void **req)
3022
0
{
3023
0
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
3024
0
    void *ret_value       = NULL;  /* Return value */
3025
3026
0
    FUNC_ENTER_NOAPI(NULL)
3027
3028
    /* Set wrapper info in API context */
3029
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
3030
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
3031
0
    vol_wrapper_set = true;
3032
3033
    /* Call the corresponding internal VOL routine */
3034
0
    if (NULL == (ret_value = H5VL__datatype_open(vol_obj->data, loc_params, vol_obj->connector->cls, name,
3035
0
                                                 tapl_id, dxpl_id, req)))
3036
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "datatype open failed");
3037
3038
0
done:
3039
    /* Reset object wrapping info in API context */
3040
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
3041
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
3042
3043
0
    FUNC_LEAVE_NOAPI(ret_value)
3044
0
} /* end H5VL_datatype_open() */
3045
3046
/*-------------------------------------------------------------------------
3047
 * Function:    H5VLdatatype_open
3048
 *
3049
 * Purpose:     Opens a named datatype
3050
 *
3051
 * Return:      Success:    Pointer to the datatype
3052
 *              Failure:    NULL
3053
 *
3054
 *-------------------------------------------------------------------------
3055
 */
3056
void *
3057
H5VLdatatype_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
3058
                  hid_t tapl_id, hid_t dxpl_id, void **req /*out*/)
3059
0
{
3060
0
    H5VL_connector_t *connector;        /* VOL connector */
3061
0
    void             *ret_value = NULL; /* Return value */
3062
3063
0
    FUNC_ENTER_API_NOINIT
3064
3065
    /* Check args and get connector pointer */
3066
0
    if (NULL == obj)
3067
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
3068
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
3069
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
3070
3071
    /* Call the corresponding internal VOL routine */
3072
0
    if (NULL ==
3073
0
        (ret_value = H5VL__datatype_open(obj, loc_params, connector->cls, name, tapl_id, dxpl_id, req)))
3074
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "unable to open datatype");
3075
3076
0
done:
3077
0
    FUNC_LEAVE_API_NOINIT(ret_value)
3078
0
} /* end H5VLdatatype_open() */
3079
3080
/*-------------------------------------------------------------------------
3081
 * Function:    H5VL__datatype_get
3082
 *
3083
 * Purpose:     Get specific information about the datatype through the VOL
3084
 *
3085
 * Return:      Success:    Non-negative
3086
 *              Failure:    Negative
3087
 *
3088
 *-------------------------------------------------------------------------
3089
 */
3090
static herr_t
3091
H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_args_t *args, hid_t dxpl_id,
3092
                   void **req)
3093
0
{
3094
0
    herr_t ret_value = SUCCEED; /* Return value */
3095
3096
0
    FUNC_ENTER_PACKAGE
3097
3098
    /* Check if the corresponding VOL callback exists */
3099
0
    if (NULL == cls->datatype_cls.get)
3100
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype get' method");
3101
3102
    /* Prepare & restore library for user callback */
3103
0
    H5_BEFORE_USER_CB(FAIL)
3104
0
        {
3105
            /* Call the corresponding VOL callback */
3106
0
            ret_value = (cls->datatype_cls.get)(obj, args, dxpl_id, req);
3107
0
        }
3108
0
    H5_AFTER_USER_CB(FAIL)
3109
0
    if (ret_value < 0)
3110
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype 'get' failed");
3111
3112
0
done:
3113
0
    FUNC_LEAVE_NOAPI(ret_value)
3114
0
} /* end H5VL__datatype_get() */
3115
3116
/*-------------------------------------------------------------------------
3117
 * Function:    H5VL_datatype_get
3118
 *
3119
 * Purpose:     Get specific information about the datatype through the VOL
3120
 *
3121
 * Return:      Success:    Non-negative
3122
 *              Failure:    Negative
3123
 *
3124
 *-------------------------------------------------------------------------
3125
 */
3126
herr_t
3127
H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req)
3128
0
{
3129
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
3130
0
    herr_t ret_value       = SUCCEED; /* Return value */
3131
3132
0
    FUNC_ENTER_NOAPI(FAIL)
3133
3134
    /* Set wrapper info in API context */
3135
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
3136
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
3137
0
    vol_wrapper_set = true;
3138
3139
    /* Call the corresponding internal VOL routine */
3140
0
    if (H5VL__datatype_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
3141
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype get failed");
3142
3143
0
done:
3144
    /* Reset object wrapping info in API context */
3145
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
3146
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
3147
3148
0
    FUNC_LEAVE_NOAPI(ret_value)
3149
0
} /* end H5VL_datatype_get() */
3150
3151
/*-------------------------------------------------------------------------
3152
 * Function:    H5VLdatatype_get
3153
 *
3154
 * Purpose:     Gets information about the datatype
3155
 *
3156
 * Return:      Success:    Non-negative
3157
 *              Failure:    Negative
3158
 *
3159
 *-------------------------------------------------------------------------
3160
 */
3161
herr_t
3162
H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_args_t *args, hid_t dxpl_id,
3163
                 void **req /*out*/)
3164
0
{
3165
0
    H5VL_connector_t *connector;           /* VOL connector */
3166
0
    herr_t            ret_value = SUCCEED; /* Return value */
3167
3168
0
    FUNC_ENTER_API_NOINIT
3169
3170
    /* Check args and get connector pointer */
3171
0
    if (NULL == obj)
3172
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
3173
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
3174
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
3175
3176
    /* Call the corresponding internal VOL routine */
3177
0
    if (H5VL__datatype_get(obj, connector->cls, args, dxpl_id, req) < 0)
3178
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute datatype get callback");
3179
3180
0
done:
3181
0
    FUNC_LEAVE_API_NOINIT(ret_value)
3182
0
} /* end H5VLdatatype_get() */
3183
3184
/*-------------------------------------------------------------------------
3185
 * Function:  H5VL__datatype_specific
3186
 *
3187
 * Purpose: Specific operation on datatypes through the VOL
3188
 *
3189
 * Return:      Success:    Non-negative
3190
 *              Failure:    Negative
3191
 *
3192
 *-------------------------------------------------------------------------
3193
 */
3194
static herr_t
3195
H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_args_t *args,
3196
                        hid_t dxpl_id, void **req)
3197
0
{
3198
0
    herr_t ret_value = SUCCEED; /* Return value */
3199
3200
0
    FUNC_ENTER_PACKAGE
3201
3202
    /* Check if the corresponding VOL callback exists */
3203
0
    if (NULL == cls->datatype_cls.specific)
3204
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype specific' method");
3205
3206
    /* Prepare & restore library for user callback */
3207
0
    H5_BEFORE_USER_CB(FAIL)
3208
0
        {
3209
            /* Call the corresponding VOL callback */
3210
0
            ret_value = (cls->datatype_cls.specific)(obj, args, dxpl_id, req);
3211
0
        }
3212
0
    H5_AFTER_USER_CB(FAIL)
3213
0
    if (ret_value < 0)
3214
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback");
3215
3216
0
done:
3217
0
    FUNC_LEAVE_NOAPI(ret_value)
3218
0
} /* end H5VL__datatype_specific() */
3219
3220
/*-------------------------------------------------------------------------
3221
 * Function:  H5VL_datatype_specific
3222
 *
3223
 * Purpose: Specific operation on datatypes through the VOL
3224
 *
3225
 * Return:      Success:    Non-negative
3226
 *              Failure:    Negative
3227
 *
3228
 *-------------------------------------------------------------------------
3229
 */
3230
herr_t
3231
H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_args_t *args, hid_t dxpl_id,
3232
                       void **req)
3233
0
{
3234
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
3235
0
    herr_t ret_value       = SUCCEED; /* Return value */
3236
3237
0
    FUNC_ENTER_NOAPI(FAIL)
3238
3239
    /* Set wrapper info in API context */
3240
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
3241
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
3242
0
    vol_wrapper_set = true;
3243
3244
    /* Call the corresponding internal VOL routine */
3245
0
    if (H5VL__datatype_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
3246
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback");
3247
3248
0
done:
3249
    /* Reset object wrapping info in API context */
3250
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
3251
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
3252
3253
0
    FUNC_LEAVE_NOAPI(ret_value)
3254
0
} /* end H5VL_datatype_specific() */
3255
3256
/*-------------------------------------------------------------------------
3257
 * Function:    H5VLdatatype_specific
3258
 *
3259
 * Purpose:     Performs a connector-specific operation on a datatype
3260
 *
3261
 * Return:      Success:    Non-negative
3262
 *              Failure:    Negative
3263
 *
3264
 *-------------------------------------------------------------------------
3265
 */
3266
herr_t
3267
H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_args_t *args, hid_t dxpl_id,
3268
                      void **req /*out*/)
3269
0
{
3270
0
    H5VL_connector_t *connector;           /* VOL connector */
3271
0
    herr_t            ret_value = SUCCEED; /* Return value */
3272
3273
0
    FUNC_ENTER_API_NOINIT
3274
3275
    /* Check args and get connector pointer */
3276
0
    if (NULL == obj)
3277
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
3278
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
3279
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
3280
3281
    /* Call the corresponding internal VOL routine */
3282
0
    if (H5VL__datatype_specific(obj, connector->cls, args, dxpl_id, req) < 0)
3283
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback");
3284
3285
0
done:
3286
0
    FUNC_LEAVE_API_NOINIT(ret_value)
3287
0
} /* end H5VLdatatype_specific() */
3288
3289
/*-------------------------------------------------------------------------
3290
 * Function:  H5VL__datatype_optional
3291
 *
3292
 * Purpose: Optional operation specific to connectors.
3293
 *
3294
 * Return:      Success:    Non-negative
3295
 *              Failure:    Negative
3296
 *
3297
 *-------------------------------------------------------------------------
3298
 */
3299
static herr_t
3300
H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id,
3301
                        void **req)
3302
0
{
3303
0
    herr_t ret_value = SUCCEED; /* Return value */
3304
3305
0
    FUNC_ENTER_PACKAGE
3306
3307
    /* Check if the corresponding VOL callback exists */
3308
0
    if (NULL == cls->datatype_cls.optional)
3309
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype optional' method");
3310
3311
    /* Prepare & restore library for user callback */
3312
0
    H5_BEFORE_USER_CB(FAIL)
3313
0
        {
3314
            /* Call the corresponding VOL callback */
3315
0
            ret_value = (cls->datatype_cls.optional)(obj, args, dxpl_id, req);
3316
0
        }
3317
0
    H5_AFTER_USER_CB(FAIL)
3318
0
    if (ret_value < 0)
3319
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback");
3320
3321
0
done:
3322
0
    FUNC_LEAVE_NOAPI(ret_value)
3323
0
} /* end H5VL__datatype_optional() */
3324
3325
/*-------------------------------------------------------------------------
3326
 * Function:  H5VL_datatype_optional
3327
 *
3328
 * Purpose: Optional operation specific to connectors.
3329
 *
3330
 * Return:      Success:    Non-negative
3331
 *              Failure:    Negative
3332
 *
3333
 *-------------------------------------------------------------------------
3334
 */
3335
herr_t
3336
H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
3337
0
{
3338
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
3339
0
    herr_t ret_value       = SUCCEED; /* Return value */
3340
3341
0
    FUNC_ENTER_NOAPI(FAIL)
3342
3343
    /* Set wrapper info in API context */
3344
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
3345
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
3346
0
    vol_wrapper_set = true;
3347
3348
    /* Call the corresponding internal VOL routine */
3349
0
    if (H5VL__datatype_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
3350
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback");
3351
3352
0
done:
3353
    /* Reset object wrapping info in API context */
3354
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
3355
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
3356
3357
0
    FUNC_LEAVE_NOAPI(ret_value)
3358
0
} /* end H5VL_datatype_optional() */
3359
3360
/*-------------------------------------------------------------------------
3361
 * Function:  H5VL_datatype_optional_op
3362
 *
3363
 * Purpose: Optional operation specific to connectors.
3364
 *
3365
 * Return:      Success:    Non-negative
3366
 *              Failure:    Negative
3367
 *
3368
 *-------------------------------------------------------------------------
3369
 */
3370
herr_t
3371
H5VL_datatype_optional_op(H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req,
3372
                          H5VL_object_t **_vol_obj_ptr)
3373
0
{
3374
0
    H5VL_object_t  *tmp_vol_obj = NULL;                                         /* Object for id */
3375
0
    H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for id */
3376
0
    bool            vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
3377
0
    herr_t          ret_value       = SUCCEED; /* Return value */
3378
3379
0
    FUNC_ENTER_NOAPI(FAIL)
3380
3381
    /* Sanity check */
3382
0
    assert(vol_obj);
3383
3384
    /* Set up vol_obj_ptr */
3385
0
    *vol_obj_ptr = vol_obj;
3386
3387
    /* Set wrapper info in API context */
3388
0
    if (H5VL_set_vol_wrapper(*vol_obj_ptr) < 0)
3389
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
3390
0
    vol_wrapper_set = true;
3391
3392
    /* Call the corresponding internal VOL routine */
3393
0
    if (H5VL__datatype_optional((*vol_obj_ptr)->data, (*vol_obj_ptr)->connector->cls, args, dxpl_id, req) < 0)
3394
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback");
3395
3396
0
done:
3397
    /* Reset object wrapping info in API context */
3398
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
3399
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
3400
3401
0
    FUNC_LEAVE_NOAPI(ret_value)
3402
0
} /* end H5VL_datatype_optional_op() */
3403
3404
/*-------------------------------------------------------------------------
3405
 * Function:    H5VLdatatype_optional
3406
 *
3407
 * Purpose:     Performs an optional connector-specific operation on a datatype
3408
 *
3409
 * Return:      Success:    Non-negative
3410
 *              Failure:    Negative
3411
 *
3412
 *-------------------------------------------------------------------------
3413
 */
3414
herr_t
3415
H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id,
3416
                      void **req /*out*/)
3417
0
{
3418
0
    H5VL_connector_t *connector;           /* VOL connector */
3419
0
    herr_t            ret_value = SUCCEED; /* Return value */
3420
3421
0
    FUNC_ENTER_API_NOINIT
3422
3423
    /* Check args and get connector pointer */
3424
0
    if (NULL == obj)
3425
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
3426
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
3427
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
3428
3429
    /* Call the corresponding internal VOL routine */
3430
0
    if (H5VL__datatype_optional(obj, connector->cls, args, dxpl_id, req) < 0)
3431
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback");
3432
3433
0
done:
3434
0
    FUNC_LEAVE_API_NOINIT(ret_value)
3435
0
} /* end H5VLdatatype_optional() */
3436
3437
/*-------------------------------------------------------------------------
3438
 * Function:    H5VLdatatype_optional_op
3439
 *
3440
 * Purpose:     Performs an optional connector-specific operation on a datatype
3441
 *
3442
 * Return:      Success:    Non-negative
3443
 *              Failure:    Negative
3444
 *
3445
 *-------------------------------------------------------------------------
3446
 */
3447
herr_t
3448
H5VLdatatype_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id,
3449
                         H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id)
3450
0
{
3451
0
    H5T_t         *dt;                          /* Datatype for this operation */
3452
0
    H5VL_object_t *vol_obj   = NULL;            /* Datatype VOL object */
3453
0
    void          *token     = NULL;            /* Request token for async operation        */
3454
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
3455
0
    herr_t         ret_value = SUCCEED;         /* Return value */
3456
3457
0
    FUNC_ENTER_API(FAIL)
3458
3459
    /* Check args */
3460
0
    if (NULL == (dt = H5I_object_verify(type_id, H5I_DATATYPE)))
3461
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
3462
3463
    /* Set up request token pointer for asynchronous operation */
3464
0
    if (H5ES_NONE != es_id)
3465
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
3466
3467
    /* Only invoke callback if VOL object is set for the datatype */
3468
0
    if (H5T_invoke_vol_optional(dt, args, dxpl_id, token_ptr, &vol_obj) < 0)
3469
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to invoke datatype optional callback");
3470
3471
    /* If a token was created, add the token to the event set */
3472
0
    if (NULL != token)
3473
        /* clang-format off */
3474
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
3475
0
                        H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, type_id, args, dxpl_id, es_id)) < 0)
3476
            /* clang-format on */
3477
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set");
3478
3479
0
done:
3480
0
    FUNC_LEAVE_API(ret_value)
3481
0
} /* end H5VLdatatype_optional_op() */
3482
3483
/*-------------------------------------------------------------------------
3484
 * Function:    H5VL__datatype_close
3485
 *
3486
 * Purpose:     Closes a datatype through the VOL
3487
 *
3488
 * Return:      Success:    Non-negative
3489
 *              Failure:    Negative
3490
 *
3491
 *-------------------------------------------------------------------------
3492
 */
3493
static herr_t
3494
H5VL__datatype_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req)
3495
0
{
3496
0
    herr_t ret_value = SUCCEED; /* Return value */
3497
3498
0
    FUNC_ENTER_PACKAGE
3499
3500
    /* Check if the corresponding VOL callback exists */
3501
0
    if (NULL == cls->datatype_cls.close)
3502
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype close' method");
3503
3504
    /* Prepare & restore library for user callback */
3505
0
    H5_BEFORE_USER_CB(FAIL)
3506
0
        {
3507
            /* Call the corresponding VOL callback */
3508
0
            ret_value = (cls->datatype_cls.close)(obj, dxpl_id, req);
3509
0
        }
3510
0
    H5_AFTER_USER_CB(FAIL)
3511
0
    if (ret_value < 0)
3512
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "datatype close failed");
3513
3514
0
done:
3515
0
    FUNC_LEAVE_NOAPI(ret_value)
3516
0
} /* end H5VL__datatype_close() */
3517
3518
/*-------------------------------------------------------------------------
3519
 * Function:    H5VL_datatype_close
3520
 *
3521
 * Purpose:     Closes a datatype through the VOL
3522
 *
3523
 * Return:      Success:    Non-negative
3524
 *              Failure:    Negative
3525
 *
3526
 *-------------------------------------------------------------------------
3527
 */
3528
herr_t
3529
H5VL_datatype_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req)
3530
0
{
3531
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
3532
0
    herr_t ret_value       = SUCCEED; /* Return value */
3533
3534
0
    FUNC_ENTER_NOAPI(FAIL)
3535
3536
    /* Set wrapper info in API context */
3537
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
3538
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
3539
0
    vol_wrapper_set = true;
3540
3541
    /* Call the corresponding internal VOL routine */
3542
0
    if (H5VL__datatype_close(vol_obj->data, vol_obj->connector->cls, dxpl_id, req) < 0)
3543
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "datatype close failed");
3544
3545
0
done:
3546
    /* Reset object wrapping info in API context */
3547
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
3548
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
3549
3550
0
    FUNC_LEAVE_NOAPI(ret_value)
3551
0
} /* end H5VL_datatype_close() */
3552
3553
/*-------------------------------------------------------------------------
3554
 * Function:    H5VLdatatype_close
3555
 *
3556
 * Purpose:     Closes a datatype
3557
 *
3558
 * Return:      Success:    Non-negative
3559
 *              Failure:    Negative
3560
 *
3561
 *-------------------------------------------------------------------------
3562
 */
3563
herr_t
3564
H5VLdatatype_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/)
3565
0
{
3566
0
    H5VL_connector_t *connector;           /* VOL connector */
3567
0
    herr_t            ret_value = SUCCEED; /* Return value */
3568
3569
0
    FUNC_ENTER_API_NOINIT
3570
3571
    /* Check args and get connector pointer */
3572
0
    if (NULL == obj)
3573
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
3574
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
3575
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
3576
3577
    /* Call the corresponding internal VOL routine */
3578
0
    if (H5VL__datatype_close(obj, connector->cls, dxpl_id, req) < 0)
3579
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "unable to close datatype");
3580
3581
0
done:
3582
0
    FUNC_LEAVE_API_NOINIT(ret_value)
3583
0
} /* end H5VLdatatype_close() */
3584
3585
/*-------------------------------------------------------------------------
3586
 * Function:  H5VL__file_create
3587
 *
3588
 * Purpose: Creates a file through the VOL
3589
 *
3590
 * Note:  Does not have a 'static' version of the routine, since there's
3591
 *    no objects in the container before this operation completes.
3592
 *
3593
 * Return:      Success: Pointer to new file
3594
 *    Failure: NULL
3595
 *
3596
 *-------------------------------------------------------------------------
3597
 */
3598
static void *
3599
H5VL__file_create(const H5VL_class_t *cls, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
3600
                  hid_t dxpl_id, void **req)
3601
0
{
3602
0
    void *ret_value = NULL; /* Return value */
3603
3604
0
    FUNC_ENTER_PACKAGE
3605
3606
    /* Check if the corresponding VOL callback exists */
3607
0
    if (NULL == cls->file_cls.create)
3608
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'file create' method");
3609
3610
    /* Prepare & restore library for user callback */
3611
0
    H5_BEFORE_USER_CB(NULL)
3612
0
        {
3613
            /* Call the corresponding VOL callback */
3614
0
            ret_value = (cls->file_cls.create)(name, flags, fcpl_id, fapl_id, dxpl_id, req);
3615
0
        }
3616
0
    H5_AFTER_USER_CB(NULL)
3617
0
    if (NULL == ret_value)
3618
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "file create failed");
3619
3620
0
done:
3621
0
    FUNC_LEAVE_NOAPI(ret_value)
3622
0
} /* end H5VL__file_create() */
3623
3624
/*-------------------------------------------------------------------------
3625
 * Function:  H5VL_file_create
3626
 *
3627
 * Purpose: Creates a file through the VOL
3628
 *
3629
 * Note:  Does not have a 'static' version of the routine, since there's
3630
 *    no objects in the container before this operation completes.
3631
 *
3632
 * Return:      Success: Pointer to new file
3633
 *    Failure: NULL
3634
 *
3635
 *-------------------------------------------------------------------------
3636
 */
3637
void *
3638
H5VL_file_create(const H5VL_connector_t *connector, const char *name, unsigned flags, hid_t fcpl_id,
3639
                 hid_t fapl_id, hid_t dxpl_id, void **req)
3640
0
{
3641
0
    void *ret_value = NULL; /* Return value */
3642
3643
0
    FUNC_ENTER_NOAPI(NULL)
3644
3645
    /* Call the corresponding internal VOL routine */
3646
0
    if (NULL == (ret_value = H5VL__file_create(connector->cls, name, flags, fcpl_id, fapl_id, dxpl_id, req)))
3647
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "file create failed");
3648
3649
0
done:
3650
0
    FUNC_LEAVE_NOAPI(ret_value)
3651
0
} /* end H5VL_file_create() */
3652
3653
/*-------------------------------------------------------------------------
3654
 * Function:    H5VLfile_create
3655
 *
3656
 * Purpose:     Creates a file
3657
 *
3658
 * Return:      Success:    Pointer to the new file
3659
 *              Failure:    NULL
3660
 *
3661
 *-------------------------------------------------------------------------
3662
 */
3663
void *
3664
H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id,
3665
                void **req /*out*/)
3666
0
{
3667
0
    H5P_genplist_t       *plist;            /* Property list pointer */
3668
0
    H5VL_connector_prop_t connector_prop;   /* Property for VOL connector ID & info */
3669
0
    void                 *ret_value = NULL; /* Return value */
3670
3671
0
    FUNC_ENTER_API_NOINIT
3672
3673
    /* Get the VOL info from the fapl */
3674
0
    if (NULL == (plist = H5I_object(fapl_id)))
3675
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
3676
0
    if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
3677
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get VOL connector info");
3678
3679
    /* Call the corresponding internal VOL routine */
3680
0
    if (NULL == (ret_value = H5VL__file_create(connector_prop.connector->cls, name, flags, fcpl_id, fapl_id,
3681
0
                                               dxpl_id, req)))
3682
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "unable to create file");
3683
3684
0
done:
3685
0
    FUNC_LEAVE_API_NOINIT(ret_value)
3686
0
} /* end H5VLfile_create() */
3687
3688
/*-------------------------------------------------------------------------
3689
 * Function:  H5VL__file_open
3690
 *
3691
 * Purpose: Opens a file through the VOL.
3692
 *
3693
 * Return:      Success: Pointer to file.
3694
 *    Failure: NULL
3695
 *
3696
 *-------------------------------------------------------------------------
3697
 */
3698
static void *
3699
H5VL__file_open(const H5VL_class_t *cls, const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id,
3700
                void **req)
3701
784
{
3702
784
    void *ret_value = NULL; /* Return value */
3703
3704
784
    FUNC_ENTER_PACKAGE
3705
3706
    /* Check if the corresponding VOL callback exists */
3707
784
    if (NULL == cls->file_cls.open)
3708
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'file open' method");
3709
3710
    /* Prepare & restore library for user callback */
3711
784
    H5_BEFORE_USER_CB(NULL)
3712
784
        {
3713
            /* Call the corresponding VOL callback */
3714
784
            ret_value = (cls->file_cls.open)(name, flags, fapl_id, dxpl_id, req);
3715
784
        }
3716
784
    H5_AFTER_USER_CB(NULL)
3717
784
    if (NULL == ret_value)
3718
111
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed");
3719
3720
784
done:
3721
784
    FUNC_LEAVE_NOAPI(ret_value)
3722
784
} /* end H5VL__file_open() */
3723
3724
/*-------------------------------------------------------------------------
3725
 * Function:    H5VL__file_open_find_connector_cb
3726
 *
3727
 * Purpose:     Iteration callback for H5PL_iterate that tries to find the
3728
 *              correct VOL connector to open a file with when
3729
 *              H5VL_file_open fails for its given VOL connector. Iterates
3730
 *              through all of the available VOL connector plugins until
3731
 *              H5Fis_accessible returns true for the given filename and
3732
 *              VOL connector.
3733
 *
3734
 * Return:      H5_ITER_CONT if current plugin can't open the given file
3735
 *              H5_ITER_STOP if current plugin can open given file
3736
 *              H5_ITER_ERROR if an error occurs while trying to determine
3737
 *                  if current plugin can open given file.
3738
 *
3739
 *-------------------------------------------------------------------------
3740
 */
3741
static herr_t
3742
H5VL__file_open_find_connector_cb(H5PL_type_t H5_ATTR_UNUSED plugin_type,
3743
                                  const void H5_ATTR_UNUSED *plugin_info, void *op_data)
3744
0
{
3745
0
    H5VL_file_open_find_connector_t *udata = (H5VL_file_open_find_connector_t *)op_data;
3746
0
    H5VL_file_specific_args_t        vol_cb_args; /* Arguments to VOL callback */
3747
0
    H5VL_connector_t                *connector = NULL;
3748
0
    const H5VL_class_t              *cls       = (const H5VL_class_t *)plugin_info;
3749
0
    H5P_genplist_t                  *fapl_plist;
3750
0
    H5P_genplist_t                  *fapl_plist_copy;
3751
0
    herr_t                           status;
3752
0
    bool                             is_accessible = false; /* Whether file is accessible */
3753
0
    hid_t                            fapl_id       = H5I_INVALID_HID;
3754
0
    herr_t                           ret_value     = H5_ITER_CONT;
3755
3756
0
    FUNC_ENTER_PACKAGE
3757
3758
0
    assert(udata);
3759
0
    assert(udata->filename);
3760
0
    assert(cls);
3761
0
    assert(plugin_type == H5PL_TYPE_VOL);
3762
3763
    /* Attempt to register plugin as a VOL connector */
3764
0
    if (NULL == (connector = H5VL__register_connector_by_class(cls, H5P_VOL_INITIALIZE_DEFAULT)))
3765
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5_ITER_ERROR, "unable to register VOL connector");
3766
3767
    /* Setup FAPL with registered VOL connector */
3768
0
    if (NULL == (fapl_plist = H5I_object_verify(udata->fapl_id, H5I_GENPROP_LST)))
3769
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "not a property list");
3770
0
    if ((fapl_id = H5P_copy_plist(fapl_plist, true)) < 0)
3771
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy fapl");
3772
0
    if (NULL == (fapl_plist_copy = H5I_object_verify(fapl_id, H5I_GENPROP_LST)))
3773
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "not a property list");
3774
0
    if (H5P_set_vol(fapl_plist_copy, connector, NULL) < 0)
3775
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, H5_ITER_ERROR, "can't set VOL connector on fapl");
3776
3777
    /* Set up VOL callback arguments */
3778
0
    vol_cb_args.op_type                       = H5VL_FILE_IS_ACCESSIBLE;
3779
0
    vol_cb_args.args.is_accessible.filename   = udata->filename;
3780
0
    vol_cb_args.args.is_accessible.fapl_id    = fapl_id;
3781
0
    vol_cb_args.args.is_accessible.accessible = &is_accessible;
3782
3783
0
    H5E_PAUSE_ERRORS
3784
0
        {
3785
0
            status = H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL);
3786
0
        }
3787
0
    H5E_RESUME_ERRORS
3788
3789
0
    if (status >= 0 && is_accessible) {
3790
        /* If the file was accessible with the current VOL connector, return
3791
         * the FAPL with that VOL connector set on it.
3792
         */
3793
0
        udata->fapl_id = fapl_id;
3794
0
        udata->cls     = cls;
3795
0
        ret_value      = H5_ITER_STOP;
3796
0
    }
3797
3798
0
done:
3799
0
    if (ret_value != H5_ITER_STOP) {
3800
0
        if (fapl_id >= 0 && H5I_dec_app_ref(fapl_id) < 0)
3801
0
            HDONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "can't close fapl");
3802
3803
0
        if (connector && H5VL_conn_dec_rc(connector) < 0)
3804
0
            HDONE_ERROR(H5E_ID, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "can't close VOL connector");
3805
0
    }
3806
3807
0
    FUNC_LEAVE_NOAPI(ret_value)
3808
0
} /* end H5VL__file_open_find_connector_cb() */
3809
3810
/*-------------------------------------------------------------------------
3811
 * Function:  H5VL_file_open
3812
 *
3813
 * Purpose: Opens a file through the VOL.
3814
 *
3815
 * Note:  Does not have a 'static' version of the routine, since there's
3816
 *    no objects in the container before this operation completes.
3817
 *
3818
 * Return:      Success: Pointer to file.
3819
 *    Failure: NULL
3820
 *
3821
 *-------------------------------------------------------------------------
3822
 */
3823
void *
3824
H5VL_file_open(H5VL_connector_t *connector, const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id,
3825
               void **req)
3826
784
{
3827
784
    void *ret_value = NULL; /* Return value */
3828
3829
784
    FUNC_ENTER_NOAPI(NULL)
3830
3831
    /* Call the corresponding internal VOL routine */
3832
784
    if (NULL == (ret_value = H5VL__file_open(connector->cls, name, flags, fapl_id, dxpl_id, req))) {
3833
111
        bool is_default_conn = true;
3834
3835
        /* Opening the file failed - Determine whether we should search
3836
         * the plugin path to see if any other VOL connectors are available
3837
         * to attempt to open the file with. This only occurs if the default
3838
         * VOL connector was used for the initial file open attempt.
3839
         */
3840
111
        H5VL__is_default_conn(fapl_id, connector, &is_default_conn);
3841
3842
111
        if (is_default_conn) {
3843
111
            H5VL_file_open_find_connector_t find_connector_ud;
3844
111
            herr_t                          iter_ret;
3845
3846
111
            find_connector_ud.filename = name;
3847
111
            find_connector_ud.cls      = NULL;
3848
111
            find_connector_ud.fapl_id  = fapl_id;
3849
3850
111
            iter_ret = H5PL_iterate(H5PL_ITER_TYPE_VOL, H5VL__file_open_find_connector_cb,
3851
111
                                    (void *)&find_connector_ud);
3852
111
            if (iter_ret < 0)
3853
0
                HGOTO_ERROR(H5E_VOL, H5E_BADITER, NULL,
3854
111
                            "failed to iterate over available VOL connector plugins");
3855
111
            else if (iter_ret) {
3856
                /* If one of the available VOL connector plugins is
3857
                 * able to open the file, open the file with it.
3858
                 */
3859
0
                if (NULL == (ret_value = H5VL__file_open(find_connector_ud.cls, name, flags,
3860
0
                                                         find_connector_ud.fapl_id, dxpl_id, req)))
3861
0
                    HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL,
3862
0
                                "can't open file '%s' with VOL connector '%s'", name,
3863
0
                                find_connector_ud.cls->name);
3864
0
            }
3865
111
            else
3866
                /* Otherwise, if no VOL connectors are available, throw
3867
                 * error from original file open failure.
3868
                 */
3869
111
                HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed");
3870
111
        } /* end if */
3871
0
        else
3872
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed");
3873
111
    } /* end if */
3874
3875
784
done:
3876
784
    FUNC_LEAVE_NOAPI(ret_value)
3877
784
} /* end H5VL_file_open() */
3878
3879
/*-------------------------------------------------------------------------
3880
 * Function:    H5VLfile_open
3881
 *
3882
 * Purpose:     Opens a file
3883
 *
3884
 * Return:      Success:    Pointer to the file
3885
 *              Failure:    NULL
3886
 *
3887
 *-------------------------------------------------------------------------
3888
 */
3889
void *
3890
H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req /*out*/)
3891
0
{
3892
0
    H5P_genplist_t       *plist;            /* Property list pointer */
3893
0
    H5VL_connector_prop_t connector_prop;   /* Property for VOL connector ID & info */
3894
0
    void                 *ret_value = NULL; /* Return value */
3895
3896
0
    FUNC_ENTER_API_NOINIT
3897
3898
    /* Get the VOL info from the fapl */
3899
0
    if (NULL == (plist = H5I_object(fapl_id)))
3900
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
3901
0
    if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
3902
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get VOL connector info");
3903
3904
    /* Call the corresponding internal VOL routine */
3905
0
    if (NULL ==
3906
0
        (ret_value = H5VL__file_open(connector_prop.connector->cls, name, flags, fapl_id, dxpl_id, req)))
3907
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "unable to open file");
3908
3909
0
done:
3910
0
    FUNC_LEAVE_API_NOINIT(ret_value)
3911
0
} /* end H5VLfile_open() */
3912
3913
/*-------------------------------------------------------------------------
3914
 * Function:  H5VL__file_get
3915
 *
3916
 * Purpose: Get specific information about the file through the VOL
3917
 *
3918
 * Return:      Success:    Non-negative
3919
 *              Failure:    Negative
3920
 *
3921
 *-------------------------------------------------------------------------
3922
 */
3923
static herr_t
3924
H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req)
3925
51
{
3926
51
    herr_t ret_value = SUCCEED; /* Return value */
3927
3928
51
    FUNC_ENTER_PACKAGE
3929
3930
    /* Check if the corresponding VOL callback exists */
3931
51
    if (NULL == cls->file_cls.get)
3932
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file get' method");
3933
3934
    /* Prepare & restore library for user callback */
3935
51
    H5_BEFORE_USER_CB(FAIL)
3936
51
        {
3937
            /* Call the corresponding VOL callback */
3938
51
            ret_value = (cls->file_cls.get)(obj, args, dxpl_id, req);
3939
51
        }
3940
51
    H5_AFTER_USER_CB(FAIL)
3941
51
    if (ret_value < 0)
3942
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "file get failed");
3943
3944
51
done:
3945
51
    FUNC_LEAVE_NOAPI(ret_value)
3946
51
} /* end H5VL__file_get() */
3947
3948
/*-------------------------------------------------------------------------
3949
 * Function:  H5VL_file_get
3950
 *
3951
 * Purpose: Get specific information about the file through the VOL
3952
 *
3953
 * Return:      Success:    Non-negative
3954
 *              Failure:    Negative
3955
 *
3956
 *-------------------------------------------------------------------------
3957
 */
3958
herr_t
3959
H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req)
3960
51
{
3961
51
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
3962
51
    herr_t ret_value       = SUCCEED; /* Return value */
3963
3964
51
    FUNC_ENTER_NOAPI(FAIL)
3965
3966
    /* Set wrapper info in API context */
3967
51
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
3968
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
3969
51
    vol_wrapper_set = true;
3970
3971
    /* Call the corresponding internal VOL routine */
3972
51
    if (H5VL__file_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
3973
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "file get failed");
3974
3975
51
done:
3976
    /* Reset object wrapping info in API context */
3977
51
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
3978
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
3979
3980
51
    FUNC_LEAVE_NOAPI(ret_value)
3981
51
} /* end H5VL_file_get() */
3982
3983
/*-------------------------------------------------------------------------
3984
 * Function:    H5VLfile_get
3985
 *
3986
 * Purpose:     Gets information about the file
3987
 *
3988
 * Return:      Success:    Non-negative
3989
 *              Failure:    Negative
3990
 *
3991
 *-------------------------------------------------------------------------
3992
 */
3993
herr_t
3994
H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req /*out*/)
3995
0
{
3996
0
    H5VL_connector_t *connector;           /* VOL connector */
3997
0
    herr_t            ret_value = SUCCEED; /* Return value */
3998
3999
0
    FUNC_ENTER_API_NOINIT
4000
4001
    /* Check args and get connector pointer */
4002
0
    if (NULL == obj)
4003
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
4004
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4005
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
4006
4007
    /* Call the corresponding internal VOL routine */
4008
0
    if (H5VL__file_get(obj, connector->cls, args, dxpl_id, req) < 0)
4009
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute file get callback");
4010
4011
0
done:
4012
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4013
0
} /* end H5VLfile_get() */
4014
4015
/*-------------------------------------------------------------------------
4016
 * Function:  H5VL__file_specific
4017
 *
4018
 * Purpose: Perform File specific operations through the VOL
4019
 *
4020
 * Return:      Success:    Non-negative
4021
 *              Failure:    Negative
4022
 *
4023
 *-------------------------------------------------------------------------
4024
 */
4025
static herr_t
4026
H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_args_t *args, hid_t dxpl_id,
4027
                    void **req)
4028
0
{
4029
0
    herr_t ret_value = SUCCEED; /* Return value */
4030
4031
0
    FUNC_ENTER_PACKAGE
4032
4033
    /* Check if the corresponding VOL callback exists */
4034
0
    if (NULL == cls->file_cls.specific)
4035
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file specific' method");
4036
4037
    /* Prepare & restore library for user callback */
4038
0
    H5_BEFORE_USER_CB(FAIL)
4039
0
        {
4040
            /* Call the corresponding VOL callback */
4041
0
            ret_value = (cls->file_cls.specific)(obj, args, dxpl_id, req);
4042
0
        }
4043
0
    H5_AFTER_USER_CB(FAIL)
4044
0
    if (ret_value < 0)
4045
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed");
4046
4047
0
done:
4048
0
    FUNC_LEAVE_NOAPI(ret_value)
4049
0
} /* end H5VL__file_specific() */
4050
4051
/*-------------------------------------------------------------------------
4052
 * Function:  H5VL_file_specific
4053
 *
4054
 * Purpose: Perform file specific operations through the VOL
4055
 *
4056
 * Return:      Success:    Non-negative
4057
 *              Failure:    Negative
4058
 *
4059
 *-------------------------------------------------------------------------
4060
 */
4061
herr_t
4062
H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req)
4063
0
{
4064
0
    const H5VL_class_t *cls;                       /* VOL connector's class struct */
4065
0
    bool                vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
4066
0
    herr_t              ret_value       = SUCCEED; /* Return value */
4067
4068
0
    FUNC_ENTER_NOAPI(FAIL)
4069
4070
    /* Special treatment of file access check & delete operations */
4071
    /* (Retrieve the VOL connector from the FAPL, since the file isn't open) */
4072
0
    if (args->op_type == H5VL_FILE_IS_ACCESSIBLE || args->op_type == H5VL_FILE_DELETE) {
4073
0
        H5P_genplist_t       *plist;          /* Property list pointer */
4074
0
        H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */
4075
0
        hid_t                 fapl_id;        /* File access property list for accessing the file */
4076
4077
        /* Get the file access property list to access the file */
4078
0
        if (args->op_type == H5VL_FILE_IS_ACCESSIBLE)
4079
0
            fapl_id = args->args.is_accessible.fapl_id;
4080
0
        else {
4081
0
            assert(args->op_type == H5VL_FILE_DELETE);
4082
0
            fapl_id = args->args.del.fapl_id;
4083
0
        }
4084
4085
        /* Get the VOL info from the FAPL */
4086
0
        if (NULL == (plist = H5I_object(fapl_id)))
4087
0
            HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a file access property list");
4088
0
        if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
4089
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get VOL connector info");
4090
4091
        /* Get class pointer */
4092
0
        cls = connector_prop.connector->cls;
4093
0
    } /* end if */
4094
    /* Set wrapper info in API context, for all other operations */
4095
0
    else {
4096
        /* Sanity check */
4097
0
        assert(vol_obj);
4098
4099
0
        if (H5VL_set_vol_wrapper(vol_obj) < 0)
4100
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
4101
0
        vol_wrapper_set = true;
4102
4103
        /* Set the VOL connector class pointer */
4104
0
        cls = vol_obj->connector->cls;
4105
0
    } /* end else */
4106
4107
    /* Call the corresponding internal VOL routine */
4108
0
    if (H5VL__file_specific(vol_obj ? vol_obj->data : NULL, cls, args, dxpl_id, req) < 0)
4109
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed");
4110
4111
0
done:
4112
    /* Reset object wrapping info in API context */
4113
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4114
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
4115
4116
0
    FUNC_LEAVE_NOAPI(ret_value)
4117
0
} /* end H5VL_file_specific() */
4118
4119
/*-------------------------------------------------------------------------
4120
 * Function:    H5VLfile_specific
4121
 *
4122
 * Purpose:     Performs a connector-specific operation on a file
4123
 *
4124
 * Note:  The 'obj' parameter is allowed to be NULL
4125
 *
4126
 * Return:      Success:    Non-negative
4127
 *              Failure:    Negative
4128
 *
4129
 *-------------------------------------------------------------------------
4130
 */
4131
herr_t
4132
H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_args_t *args, hid_t dxpl_id,
4133
                  void **req /*out*/)
4134
0
{
4135
0
    H5VL_connector_t *connector;           /* VOL connector */
4136
0
    herr_t            ret_value = SUCCEED; /* Return value */
4137
4138
0
    FUNC_ENTER_API_NOINIT
4139
4140
    /* Check args and get connector pointer */
4141
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4142
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
4143
4144
    /* Call the corresponding internal VOL routine */
4145
0
    if (H5VL__file_specific(obj, connector->cls, args, dxpl_id, req) < 0)
4146
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file specific callback");
4147
4148
0
done:
4149
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4150
0
} /* end H5VLfile_specific() */
4151
4152
/*-------------------------------------------------------------------------
4153
 * Function:  H5VL__file_optional
4154
 *
4155
 * Purpose: Perform a connector specific operation
4156
 *
4157
 * Return:      Success:    Non-negative
4158
 *              Failure:    Negative
4159
 *
4160
 *-------------------------------------------------------------------------
4161
 */
4162
static herr_t
4163
H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
4164
673
{
4165
673
    herr_t ret_value = SUCCEED; /* Return value */
4166
4167
673
    FUNC_ENTER_PACKAGE
4168
4169
    /* Check if the corresponding VOL callback exists */
4170
673
    if (NULL == cls->file_cls.optional)
4171
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file optional' method");
4172
4173
    /* Prepare & restore library for user callback */
4174
673
    H5_BEFORE_USER_CB(FAIL)
4175
673
        {
4176
            /* Call the corresponding VOL callback */
4177
673
            ret_value = (cls->file_cls.optional)(obj, args, dxpl_id, req);
4178
673
        }
4179
673
    H5_AFTER_USER_CB(FAIL)
4180
673
    if (ret_value < 0)
4181
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file optional failed");
4182
4183
673
done:
4184
673
    FUNC_LEAVE_NOAPI(ret_value)
4185
673
} /* end H5VL__file_optional() */
4186
4187
/*-------------------------------------------------------------------------
4188
 * Function:  H5VL_file_optional
4189
 *
4190
 * Purpose: Perform a connector specific operation
4191
 *
4192
 * Return:      Success:    Non-negative
4193
 *              Failure:    Negative
4194
 *
4195
 *-------------------------------------------------------------------------
4196
 */
4197
herr_t
4198
H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
4199
673
{
4200
673
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
4201
673
    herr_t ret_value       = SUCCEED; /* Return value */
4202
4203
673
    FUNC_ENTER_NOAPI(FAIL)
4204
4205
    /* Set wrapper info in API context */
4206
673
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
4207
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
4208
673
    vol_wrapper_set = true;
4209
4210
    /* Call the corresponding internal VOL routine */
4211
673
    if (H5VL__file_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
4212
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file optional failed");
4213
4214
673
done:
4215
    /* Reset object wrapping info in API context */
4216
673
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4217
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
4218
4219
673
    FUNC_LEAVE_NOAPI(ret_value)
4220
673
} /* end H5VL_file_optional() */
4221
4222
/*-------------------------------------------------------------------------
4223
 * Function:    H5VLfile_optional
4224
 *
4225
 * Purpose:     Performs an optional connector-specific operation on a file
4226
 *
4227
 * Return:      Success:    Non-negative
4228
 *              Failure:    Negative
4229
 *
4230
 *-------------------------------------------------------------------------
4231
 */
4232
herr_t
4233
H5VLfile_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id,
4234
                  void **req /*out*/)
4235
0
{
4236
0
    H5VL_connector_t *connector;           /* VOL connector */
4237
0
    herr_t            ret_value = SUCCEED; /* Return value */
4238
4239
0
    FUNC_ENTER_API_NOINIT
4240
4241
    /* Check args and get connector pointer */
4242
0
    if (NULL == obj)
4243
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
4244
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4245
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
4246
4247
    /* Call the corresponding internal VOL routine */
4248
0
    if (H5VL__file_optional(obj, connector->cls, args, dxpl_id, req) < 0)
4249
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file optional callback");
4250
4251
0
done:
4252
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4253
0
} /* end H5VLfile_optional() */
4254
4255
/*-------------------------------------------------------------------------
4256
 * Function:    H5VLfile_optional_op
4257
 *
4258
 * Purpose:     Performs an optional connector-specific operation on a file
4259
 *
4260
 * Return:      Success:    Non-negative
4261
 *              Failure:    Negative
4262
 *
4263
 *-------------------------------------------------------------------------
4264
 */
4265
herr_t
4266
H5VLfile_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id,
4267
                     H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id)
4268
0
{
4269
0
    H5VL_object_t *vol_obj   = NULL;            /* File VOL object */
4270
0
    void          *token     = NULL;            /* Request token for async operation        */
4271
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
4272
0
    herr_t         ret_value = SUCCEED;         /* Return value */
4273
4274
0
    FUNC_ENTER_API(FAIL)
4275
4276
    /* Set up request token pointer for asynchronous operation */
4277
0
    if (H5ES_NONE != es_id)
4278
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
4279
4280
    /* Call the corresponding internal VOL routine */
4281
0
    if (H5VL__common_optional_op(file_id, H5I_FILE, H5VL__file_optional, args, dxpl_id, token_ptr, &vol_obj) <
4282
0
        0)
4283
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file optional callback");
4284
4285
    /* If a token was created, add the token to the event set */
4286
0
    if (NULL != token)
4287
        /* clang-format off */
4288
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
4289
0
                        H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, file_id, args, dxpl_id, es_id)) < 0)
4290
            /* clang-format on */
4291
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set");
4292
4293
0
done:
4294
0
    FUNC_LEAVE_API(ret_value)
4295
0
} /* end H5VLfile_optional_op() */
4296
4297
/*-------------------------------------------------------------------------
4298
 * Function:    H5VL__file_close
4299
 *
4300
 * Purpose:     Closes a file through the VOL
4301
 *
4302
 * Return:      Success:    Non-negative
4303
 *              Failure:    Negative
4304
 *
4305
 *-------------------------------------------------------------------------
4306
 */
4307
static herr_t
4308
H5VL__file_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req)
4309
1.00k
{
4310
1.00k
    herr_t ret_value = SUCCEED; /* Return value */
4311
4312
1.00k
    FUNC_ENTER_PACKAGE
4313
4314
    /* Sanity check */
4315
1.00k
    assert(obj);
4316
1.00k
    assert(cls);
4317
4318
    /* Check if the corresponding VOL callback exists */
4319
1.00k
    if (NULL == cls->file_cls.close)
4320
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file close' method");
4321
4322
    /* Prepare & restore library for user callback */
4323
1.00k
    H5_BEFORE_USER_CB(FAIL)
4324
1.00k
        {
4325
            /* Call the corresponding VOL callback */
4326
1.00k
            ret_value = (cls->file_cls.close)(obj, dxpl_id, req);
4327
1.00k
        }
4328
1.00k
    H5_AFTER_USER_CB(FAIL)
4329
1.00k
    if (ret_value < 0)
4330
327
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "file close failed");
4331
4332
1.00k
done:
4333
1.00k
    FUNC_LEAVE_NOAPI(ret_value)
4334
1.00k
} /* end H5VL__file_close() */
4335
4336
/*-------------------------------------------------------------------------
4337
 * Function:    H5VL_file_close
4338
 *
4339
 * Purpose:     Closes a file through the VOL
4340
 *
4341
 * Return:      Success:    Non-negative
4342
 *              Failure:    Negative
4343
 *
4344
 *-------------------------------------------------------------------------
4345
 */
4346
herr_t
4347
H5VL_file_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req)
4348
1.00k
{
4349
1.00k
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
4350
1.00k
    herr_t ret_value       = SUCCEED; /* Return value */
4351
4352
1.00k
    FUNC_ENTER_NOAPI(FAIL)
4353
4354
    /* Set wrapper info in API context */
4355
1.00k
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
4356
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
4357
1.00k
    vol_wrapper_set = true;
4358
4359
    /* Call the corresponding internal VOL routine */
4360
1.00k
    if (H5VL__file_close(vol_obj->data, vol_obj->connector->cls, dxpl_id, req) < 0)
4361
327
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "file close failed");
4362
4363
1.00k
done:
4364
    /* Reset object wrapping info in API context */
4365
1.00k
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4366
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
4367
4368
1.00k
    FUNC_LEAVE_NOAPI(ret_value)
4369
1.00k
} /* end H5VL_file_close() */
4370
4371
/*-------------------------------------------------------------------------
4372
 * Function:    H5VLfile_close
4373
 *
4374
 * Purpose:     Closes a file
4375
 *
4376
 * Return:      Success:    Non-negative
4377
 *              Failure:    Negative
4378
 *
4379
 *-------------------------------------------------------------------------
4380
 */
4381
herr_t
4382
H5VLfile_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/)
4383
0
{
4384
0
    H5VL_connector_t *connector;           /* VOL connector */
4385
0
    herr_t            ret_value = SUCCEED; /* Return value */
4386
4387
0
    FUNC_ENTER_API_NOINIT
4388
4389
    /* Check args and get connector pointer */
4390
0
    if (NULL == obj)
4391
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
4392
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4393
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
4394
4395
    /* Call the corresponding internal VOL routine */
4396
0
    if (H5VL__file_close(obj, connector->cls, dxpl_id, req) < 0)
4397
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "unable to close file");
4398
4399
0
done:
4400
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4401
0
} /* end H5VLfile_close() */
4402
4403
/*-------------------------------------------------------------------------
4404
 * Function:  H5VL__group_create
4405
 *
4406
 * Purpose: Creates a group through the VOL
4407
 *
4408
 * Return:      Success: Pointer to new group
4409
 *    Failure: NULL
4410
 *
4411
 *-------------------------------------------------------------------------
4412
 */
4413
static void *
4414
H5VL__group_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name,
4415
                   hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req)
4416
0
{
4417
0
    void *ret_value = NULL; /* Return value */
4418
4419
0
    FUNC_ENTER_PACKAGE
4420
4421
    /* Check if the corresponding VOL callback exists */
4422
0
    if (NULL == cls->group_cls.create)
4423
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'group create' method");
4424
4425
    /* Prepare & restore library for user callback */
4426
0
    H5_BEFORE_USER_CB(NULL)
4427
0
        {
4428
            /* Call the corresponding VOL callback */
4429
0
            ret_value =
4430
0
                (cls->group_cls.create)(obj, loc_params, name, lcpl_id, gcpl_id, gapl_id, dxpl_id, req);
4431
0
        }
4432
0
    H5_AFTER_USER_CB(NULL)
4433
0
    if (NULL == ret_value)
4434
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "group create failed");
4435
4436
0
done:
4437
0
    FUNC_LEAVE_NOAPI(ret_value)
4438
0
} /* end H5VL__group_create() */
4439
4440
/*-------------------------------------------------------------------------
4441
 * Function:  H5VL_group_create
4442
 *
4443
 * Purpose: Creates a group through the VOL
4444
 *
4445
 * Return:      Success: Pointer to new group
4446
 *    Failure: NULL
4447
 *
4448
 *-------------------------------------------------------------------------
4449
 */
4450
void *
4451
H5VL_group_create(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
4452
                  hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req)
4453
0
{
4454
0
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
4455
0
    void *ret_value       = NULL;  /* Return value */
4456
4457
0
    FUNC_ENTER_NOAPI(NULL)
4458
4459
    /* Set wrapper info in API context */
4460
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
4461
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
4462
0
    vol_wrapper_set = true;
4463
4464
    /* Call the corresponding internal VOL routine */
4465
0
    if (NULL == (ret_value = H5VL__group_create(vol_obj->data, loc_params, vol_obj->connector->cls, name,
4466
0
                                                lcpl_id, gcpl_id, gapl_id, dxpl_id, req)))
4467
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "group create failed");
4468
4469
0
done:
4470
    /* Reset object wrapping info in API context */
4471
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4472
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
4473
4474
0
    FUNC_LEAVE_NOAPI(ret_value)
4475
0
} /* end H5VL_group_create() */
4476
4477
/*-------------------------------------------------------------------------
4478
 * Function:    H5VLgroup_create
4479
 *
4480
 * Purpose:     Creates a group
4481
 *
4482
 * Return:      Success:    Pointer to the new group
4483
 *              Failure:    NULL
4484
 *
4485
 *-------------------------------------------------------------------------
4486
 */
4487
void *
4488
H5VLgroup_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
4489
                 hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req /*out*/)
4490
0
{
4491
0
    H5VL_connector_t *connector;        /* VOL connector */
4492
0
    void             *ret_value = NULL; /* Return value */
4493
4494
0
    FUNC_ENTER_API_NOINIT
4495
4496
    /* Check args and get connector pointer */
4497
0
    if (NULL == obj)
4498
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
4499
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4500
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
4501
4502
    /* Call the corresponding internal VOL routine */
4503
0
    if (NULL == (ret_value = H5VL__group_create(obj, loc_params, connector->cls, name, lcpl_id, gcpl_id,
4504
0
                                                gapl_id, dxpl_id, req)))
4505
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "unable to create group");
4506
4507
0
done:
4508
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4509
0
} /* end H5VLgroup_create() */
4510
4511
/*-------------------------------------------------------------------------
4512
 * Function:  H5VL__group_open
4513
 *
4514
 * Purpose: Opens a group through the VOL
4515
 *
4516
 * Return:      Success: Pointer to group
4517
 *    Failure: NULL
4518
 *
4519
 *-------------------------------------------------------------------------
4520
 */
4521
static void *
4522
H5VL__group_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name,
4523
                 hid_t gapl_id, hid_t dxpl_id, void **req)
4524
0
{
4525
0
    void *ret_value = NULL; /* Return value */
4526
4527
0
    FUNC_ENTER_PACKAGE
4528
4529
    /* Check if the corresponding VOL callback exists */
4530
0
    if (NULL == cls->group_cls.open)
4531
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'group open' method");
4532
4533
    /* Prepare & restore library for user callback */
4534
0
    H5_BEFORE_USER_CB(NULL)
4535
0
        {
4536
            /* Call the corresponding VOL callback */
4537
0
            ret_value = (cls->group_cls.open)(obj, loc_params, name, gapl_id, dxpl_id, req);
4538
0
        }
4539
0
    H5_AFTER_USER_CB(NULL)
4540
0
    if (NULL == ret_value)
4541
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "group open failed");
4542
4543
0
done:
4544
0
    FUNC_LEAVE_NOAPI(ret_value)
4545
0
} /* end H5VL__group_open() */
4546
4547
/*-------------------------------------------------------------------------
4548
 * Function:  H5VL_group_open
4549
 *
4550
 * Purpose: Opens a group through the VOL
4551
 *
4552
 * Return:      Success: Pointer to group
4553
 *    Failure: NULL
4554
 *
4555
 *-------------------------------------------------------------------------
4556
 */
4557
void *
4558
H5VL_group_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name,
4559
                hid_t gapl_id, hid_t dxpl_id, void **req)
4560
0
{
4561
0
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
4562
0
    void *ret_value       = NULL;  /* Return value */
4563
4564
0
    FUNC_ENTER_NOAPI(NULL)
4565
4566
    /* Set wrapper info in API context */
4567
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
4568
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
4569
0
    vol_wrapper_set = true;
4570
4571
    /* Call the corresponding internal VOL routine */
4572
0
    if (NULL == (ret_value = H5VL__group_open(vol_obj->data, loc_params, vol_obj->connector->cls, name,
4573
0
                                              gapl_id, dxpl_id, req)))
4574
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "group open failed");
4575
4576
0
done:
4577
    /* Reset object wrapping info in API context */
4578
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4579
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
4580
4581
0
    FUNC_LEAVE_NOAPI(ret_value)
4582
0
} /* end H5VL_group_open() */
4583
4584
/*-------------------------------------------------------------------------
4585
 * Function:    H5VLgroup_open
4586
 *
4587
 * Purpose:     Opens a group
4588
 *
4589
 * Return:      Success:    Pointer to the group
4590
 *              Failure:    NULL
4591
 *
4592
 *-------------------------------------------------------------------------
4593
 */
4594
void *
4595
H5VLgroup_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name,
4596
               hid_t gapl_id, hid_t dxpl_id, void **req /*out*/)
4597
0
{
4598
0
    H5VL_connector_t *connector;        /* VOL connector */
4599
0
    void             *ret_value = NULL; /* Return value */
4600
4601
0
    FUNC_ENTER_API_NOINIT
4602
4603
    /* Check args and get connector pointer */
4604
0
    if (NULL == obj)
4605
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
4606
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4607
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
4608
4609
    /* Call the corresponding internal VOL routine */
4610
0
    if (NULL == (ret_value = H5VL__group_open(obj, loc_params, connector->cls, name, gapl_id, dxpl_id, req)))
4611
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to open group");
4612
4613
0
done:
4614
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4615
0
} /* end H5VLgroup_open() */
4616
4617
/*-------------------------------------------------------------------------
4618
 * Function:  H5VL__group_get
4619
 *
4620
 * Purpose: Get specific information about the group through the VOL
4621
 *
4622
 * Return:      Success:    Non-negative
4623
 *              Failure:    Negative
4624
 *
4625
 *-------------------------------------------------------------------------
4626
 */
4627
static herr_t
4628
H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req)
4629
0
{
4630
0
    herr_t ret_value = SUCCEED; /* Return value */
4631
4632
0
    FUNC_ENTER_PACKAGE
4633
4634
    /* Check if the corresponding VOL callback exists */
4635
0
    if (NULL == cls->group_cls.get)
4636
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group get' method");
4637
4638
    /* Prepare & restore library for user callback */
4639
0
    H5_BEFORE_USER_CB(FAIL)
4640
0
        {
4641
            /* Call the corresponding VOL callback */
4642
0
            ret_value = (cls->group_cls.get)(obj, args, dxpl_id, req);
4643
0
        }
4644
0
    H5_AFTER_USER_CB(FAIL)
4645
0
    if (ret_value < 0)
4646
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "group get failed");
4647
4648
0
done:
4649
0
    FUNC_LEAVE_NOAPI(ret_value)
4650
0
} /* end H5VL__group_get() */
4651
4652
/*-------------------------------------------------------------------------
4653
 * Function:  H5VL_group_get
4654
 *
4655
 * Purpose: Get specific information about the group through the VOL
4656
 *
4657
 * Return:      Success:    Non-negative
4658
 *              Failure:    Negative
4659
 *
4660
 *-------------------------------------------------------------------------
4661
 */
4662
herr_t
4663
H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req)
4664
0
{
4665
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
4666
0
    herr_t ret_value       = SUCCEED; /* Return value */
4667
4668
0
    FUNC_ENTER_NOAPI(FAIL)
4669
4670
    /* Set wrapper info in API context */
4671
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
4672
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
4673
0
    vol_wrapper_set = true;
4674
4675
    /* Call the corresponding internal VOL routine */
4676
0
    if (H5VL__group_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
4677
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "group get failed");
4678
4679
0
done:
4680
    /* Reset object wrapping info in API context */
4681
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4682
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
4683
4684
0
    FUNC_LEAVE_NOAPI(ret_value)
4685
0
} /* end H5VL_group_get() */
4686
4687
/*-------------------------------------------------------------------------
4688
 * Function:    H5VLgroup_get
4689
 *
4690
 * Purpose:     Gets information about the group
4691
 *
4692
 * Return:      Success:    Non-negative
4693
 *              Failure:    Negative
4694
 *
4695
 *-------------------------------------------------------------------------
4696
 */
4697
herr_t
4698
H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req /*out*/)
4699
0
{
4700
0
    H5VL_connector_t *connector;           /* VOL connector */
4701
0
    herr_t            ret_value = SUCCEED; /* Return value */
4702
4703
0
    FUNC_ENTER_API_NOINIT
4704
4705
    /* Check args and get connector pointer */
4706
0
    if (NULL == obj)
4707
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
4708
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4709
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
4710
4711
    /* Call the corresponding internal VOL routine */
4712
0
    if (H5VL__group_get(obj, connector->cls, args, dxpl_id, req) < 0)
4713
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute group get callback");
4714
4715
0
done:
4716
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4717
0
} /* end H5VLgroup_get() */
4718
4719
/*-------------------------------------------------------------------------
4720
 * Function:  H5VL__group_specific
4721
 *
4722
 * Purpose: Specific operation on groups through the VOL
4723
 *
4724
 * Return:      Success:    Non-negative
4725
 *              Failure:    Negative
4726
 *
4727
 *-------------------------------------------------------------------------
4728
 */
4729
static herr_t
4730
H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_args_t *args, hid_t dxpl_id,
4731
                     void **req)
4732
0
{
4733
0
    herr_t ret_value = SUCCEED; /* Return value */
4734
4735
0
    FUNC_ENTER_PACKAGE
4736
4737
    /* Check if the corresponding VOL callback exists */
4738
0
    if (NULL == cls->group_cls.specific)
4739
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group specific' method");
4740
4741
    /* Prepare & restore library for user callback */
4742
0
    H5_BEFORE_USER_CB(FAIL)
4743
0
        {
4744
            /* Call the corresponding VOL callback */
4745
0
            ret_value = (cls->group_cls.specific)(obj, args, dxpl_id, req);
4746
0
        }
4747
0
    H5_AFTER_USER_CB(FAIL)
4748
0
    if (ret_value < 0)
4749
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback");
4750
4751
0
done:
4752
0
    FUNC_LEAVE_NOAPI(ret_value)
4753
0
} /* end H5VL__group_specific() */
4754
4755
/*-------------------------------------------------------------------------
4756
 * Function:  H5VL_group_specific
4757
 *
4758
 * Purpose: Specific operation on groups through the VOL
4759
 *
4760
 * Return:      Success:    Non-negative
4761
 *              Failure:    Negative
4762
 *
4763
 *-------------------------------------------------------------------------
4764
 */
4765
herr_t
4766
H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, void **req)
4767
0
{
4768
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
4769
0
    herr_t ret_value       = SUCCEED; /* Return value */
4770
4771
0
    FUNC_ENTER_NOAPI(FAIL)
4772
4773
    /* Set wrapper info in API context */
4774
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
4775
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
4776
0
    vol_wrapper_set = true;
4777
4778
    /* Call the corresponding internal VOL routine */
4779
0
    if (H5VL__group_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0)
4780
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback");
4781
4782
0
done:
4783
    /* Reset object wrapping info in API context */
4784
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4785
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
4786
4787
0
    FUNC_LEAVE_NOAPI(ret_value)
4788
0
} /* end H5VL_group_specific() */
4789
4790
/*-------------------------------------------------------------------------
4791
 * Function:    H5VLgroup_specific
4792
 *
4793
 * Purpose:     Performs a connector-specific operation on a group
4794
 *
4795
 * Return:      Success:    Non-negative
4796
 *              Failure:    Negative
4797
 *
4798
 *-------------------------------------------------------------------------
4799
 */
4800
herr_t
4801
H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_args_t *args, hid_t dxpl_id,
4802
                   void **req /*out*/)
4803
0
{
4804
0
    H5VL_connector_t *connector;           /* VOL connector */
4805
0
    herr_t            ret_value = SUCCEED; /* Return value */
4806
4807
0
    FUNC_ENTER_API_NOINIT
4808
4809
    /* Check args and get connector pointer */
4810
0
    if (NULL == obj)
4811
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
4812
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4813
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
4814
4815
    /* Call the corresponding internal VOL routine */
4816
0
    if (H5VL__group_specific(obj, connector->cls, args, dxpl_id, req) < 0)
4817
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback");
4818
4819
0
done:
4820
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4821
0
} /* end H5VLgroup_specific() */
4822
4823
/*-------------------------------------------------------------------------
4824
 * Function:  H5VL__group_optional
4825
 *
4826
 * Purpose: Optional operation specific to connectors.
4827
 *
4828
 * Return:      Success:    Non-negative
4829
 *              Failure:    Negative
4830
 *
4831
 *-------------------------------------------------------------------------
4832
 */
4833
static herr_t
4834
H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id,
4835
                     void **req)
4836
0
{
4837
0
    herr_t ret_value = SUCCEED; /* Return value */
4838
4839
0
    FUNC_ENTER_PACKAGE
4840
4841
    /* Check if the corresponding VOL callback exists */
4842
0
    if (NULL == cls->group_cls.optional)
4843
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group optional' method");
4844
4845
    /* Prepare & restore library for user callback */
4846
0
    H5_BEFORE_USER_CB(FAIL)
4847
0
        {
4848
            /* Call the corresponding VOL callback */
4849
            /* (Must return value from callback, for iterators) */
4850
0
            ret_value = (cls->group_cls.optional)(obj, args, dxpl_id, req);
4851
0
        }
4852
0
    H5_AFTER_USER_CB(FAIL)
4853
0
    if (ret_value < 0)
4854
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback");
4855
4856
0
done:
4857
0
    FUNC_LEAVE_NOAPI(ret_value)
4858
0
} /* end H5VL__group_optional() */
4859
4860
/*-------------------------------------------------------------------------
4861
 * Function:  H5VL_group_optional
4862
 *
4863
 * Purpose: Optional operation specific to connectors.
4864
 *
4865
 * Return:      Success:    Non-negative
4866
 *              Failure:    Negative
4867
 *
4868
 *-------------------------------------------------------------------------
4869
 */
4870
herr_t
4871
H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
4872
0
{
4873
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
4874
0
    herr_t ret_value       = SUCCEED; /* Return value */
4875
4876
0
    FUNC_ENTER_NOAPI(FAIL)
4877
4878
    /* Set wrapper info in API context */
4879
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
4880
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
4881
0
    vol_wrapper_set = true;
4882
4883
    /* Call the corresponding internal VOL routine */
4884
    /* (Must return value from callback, for iterators) */
4885
0
    if ((ret_value = H5VL__group_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0)
4886
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback");
4887
4888
0
done:
4889
    /* Reset object wrapping info in API context */
4890
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
4891
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
4892
4893
0
    FUNC_LEAVE_NOAPI(ret_value)
4894
0
} /* end H5VL_group_optional() */
4895
4896
/*-------------------------------------------------------------------------
4897
 * Function:    H5VLgroup_optional
4898
 *
4899
 * Purpose:     Performs an optional connector-specific operation on a group
4900
 *
4901
 * Return:      Success:    Non-negative
4902
 *              Failure:    Negative
4903
 *
4904
 *-------------------------------------------------------------------------
4905
 */
4906
herr_t
4907
H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id,
4908
                   void **req /*out*/)
4909
0
{
4910
0
    H5VL_connector_t *connector;           /* VOL connector */
4911
0
    herr_t            ret_value = SUCCEED; /* Return value */
4912
4913
0
    FUNC_ENTER_API_NOINIT
4914
4915
    /* Check args and get connector pointer */
4916
0
    if (NULL == obj)
4917
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
4918
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
4919
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
4920
4921
    /* Call the corresponding internal VOL routine */
4922
    /* (Must return value from callback, for iterators) */
4923
0
    if ((ret_value = H5VL__group_optional(obj, connector->cls, args, dxpl_id, req)) < 0)
4924
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback");
4925
4926
0
done:
4927
0
    FUNC_LEAVE_API_NOINIT(ret_value)
4928
0
} /* end H5VLgroup_optional() */
4929
4930
/*-------------------------------------------------------------------------
4931
 * Function:    H5VLgroup_optional_op
4932
 *
4933
 * Purpose:     Performs an optional connector-specific operation on a group
4934
 *
4935
 * Return:      Success:    Non-negative
4936
 *              Failure:    Negative
4937
 *
4938
 *-------------------------------------------------------------------------
4939
 */
4940
herr_t
4941
H5VLgroup_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id,
4942
                      H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id)
4943
0
{
4944
0
    H5VL_object_t *vol_obj   = NULL;            /* Group VOL object */
4945
0
    void          *token     = NULL;            /* Request token for async operation        */
4946
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
4947
0
    herr_t         ret_value = SUCCEED;         /* Return value */
4948
4949
0
    FUNC_ENTER_API(FAIL)
4950
4951
    /* Set up request token pointer for asynchronous operation */
4952
0
    if (H5ES_NONE != es_id)
4953
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
4954
4955
    /* Call the corresponding internal VOL routine */
4956
0
    if ((ret_value = H5VL__common_optional_op(group_id, H5I_GROUP, H5VL__group_optional, args, dxpl_id,
4957
0
                                              token_ptr, &vol_obj)) < 0)
4958
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback");
4959
4960
    /* If a token was created, add the token to the event set */
4961
0
    if (NULL != token)
4962
        /* clang-format off */
4963
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
4964
0
                        H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, group_id, args, dxpl_id, es_id)) < 0)
4965
            /* clang-format on */
4966
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set");
4967
4968
0
done:
4969
0
    FUNC_LEAVE_API(ret_value)
4970
0
} /* end H5VLgroup_optional_op() */
4971
4972
/*-------------------------------------------------------------------------
4973
 * Function:    H5VL__group_close
4974
 *
4975
 * Purpose:     Closes a group through the VOL
4976
 *
4977
 * Return:      Success:    Non-negative
4978
 *              Failure:    Negative
4979
 *
4980
 *-------------------------------------------------------------------------
4981
 */
4982
static herr_t
4983
H5VL__group_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req)
4984
0
{
4985
0
    herr_t ret_value = SUCCEED; /* Return value */
4986
4987
    /* Sanity check */
4988
0
    assert(obj);
4989
0
    assert(cls);
4990
4991
0
    FUNC_ENTER_PACKAGE
4992
4993
    /* Check if the corresponding VOL callback exists */
4994
0
    if (NULL == cls->group_cls.close)
4995
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group close' method");
4996
4997
    /* Prepare & restore library for user callback */
4998
0
    H5_BEFORE_USER_CB(FAIL)
4999
0
        {
5000
            /* Call the corresponding VOL callback */
5001
0
            ret_value = (cls->group_cls.close)(obj, dxpl_id, req);
5002
0
        }
5003
0
    H5_AFTER_USER_CB(FAIL)
5004
0
    if (ret_value < 0)
5005
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "group close failed");
5006
5007
0
done:
5008
0
    FUNC_LEAVE_NOAPI(ret_value)
5009
0
} /* end H5VL__group_close() */
5010
5011
/*-------------------------------------------------------------------------
5012
 * Function:    H5VL_group_close
5013
 *
5014
 * Purpose:     Closes a group through the VOL
5015
 *
5016
 * Return:      Success:    Non-negative
5017
 *              Failure:    Negative
5018
 *
5019
 *-------------------------------------------------------------------------
5020
 */
5021
herr_t
5022
H5VL_group_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req)
5023
0
{
5024
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5025
0
    herr_t ret_value       = SUCCEED; /* Return value */
5026
5027
0
    FUNC_ENTER_NOAPI(FAIL)
5028
5029
    /* Set wrapper info in API context */
5030
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5031
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5032
0
    vol_wrapper_set = true;
5033
5034
    /* Call the corresponding internal VOL routine */
5035
0
    if (H5VL__group_close(vol_obj->data, vol_obj->connector->cls, dxpl_id, req) < 0)
5036
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "group close failed");
5037
5038
0
done:
5039
    /* Reset object wrapping info in API context */
5040
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5041
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5042
5043
0
    FUNC_LEAVE_NOAPI(ret_value)
5044
0
} /* end H5VL_group_close() */
5045
5046
/*-------------------------------------------------------------------------
5047
 * Function:    H5VLgroup_close
5048
 *
5049
 * Purpose:     Closes a group
5050
 *
5051
 * Return:      Success:    Non-negative
5052
 *              Failure:    Negative
5053
 *
5054
 *-------------------------------------------------------------------------
5055
 */
5056
herr_t
5057
H5VLgroup_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/)
5058
0
{
5059
0
    H5VL_connector_t *connector;           /* VOL connector */
5060
0
    herr_t            ret_value = SUCCEED; /* Return value */
5061
5062
0
    FUNC_ENTER_API_NOINIT
5063
5064
    /* Check args and get connector pointer */
5065
0
    if (NULL == obj)
5066
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
5067
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5068
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
5069
5070
    /* Call the corresponding internal VOL routine */
5071
0
    if (H5VL__group_close(obj, connector->cls, dxpl_id, req) < 0)
5072
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "unable to close group");
5073
5074
0
done:
5075
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5076
0
} /* end H5VLgroup_close() */
5077
5078
/*-------------------------------------------------------------------------
5079
 * Function:  H5VL__link_create
5080
 *
5081
 * Purpose: Creates a link through the VOL
5082
 *
5083
 * Note:  The 'obj' parameter is allowed to be NULL
5084
 *
5085
 * Return:      Success:    Non-negative
5086
 *              Failure:    Negative
5087
 *
5088
 *-------------------------------------------------------------------------
5089
 */
5090
static herr_t
5091
H5VL__link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params,
5092
                  const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req)
5093
0
{
5094
0
    herr_t ret_value = SUCCEED; /* Return value */
5095
5096
0
    FUNC_ENTER_PACKAGE
5097
5098
    /* Check if the corresponding VOL callback exists */
5099
0
    if (NULL == cls->link_cls.create)
5100
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link create' method");
5101
5102
    /* Prepare & restore library for user callback */
5103
0
    H5_BEFORE_USER_CB(FAIL)
5104
0
        {
5105
            /* Call the corresponding VOL callback */
5106
0
            ret_value = (cls->link_cls.create)(args, obj, loc_params, lcpl_id, lapl_id, dxpl_id, req);
5107
0
        }
5108
0
    H5_AFTER_USER_CB(FAIL)
5109
0
    if (ret_value < 0)
5110
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "link create failed");
5111
5112
0
done:
5113
0
    FUNC_LEAVE_NOAPI(ret_value)
5114
0
} /* end H5VL__link_create() */
5115
5116
/*-------------------------------------------------------------------------
5117
 * Function:  H5VL_link_create
5118
 *
5119
 * Purpose: Creates a link through the VOL
5120
 *
5121
 * Return:      Success:    Non-negative
5122
 *              Failure:    Negative
5123
 *
5124
 *-------------------------------------------------------------------------
5125
 */
5126
herr_t
5127
H5VL_link_create(H5VL_link_create_args_t *args, const H5VL_object_t *vol_obj,
5128
                 const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req)
5129
0
{
5130
0
    H5VL_object_t tmp_vol_obj;               /* Temporary VOL object */
5131
0
    bool          vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5132
0
    herr_t        ret_value       = SUCCEED; /* Return value */
5133
5134
0
    FUNC_ENTER_NOAPI(FAIL)
5135
5136
    /* Special case for hard links */
5137
0
    if (H5VL_LINK_CREATE_HARD == args->op_type && NULL == vol_obj->data)
5138
        /* Get the VOL data pointer from the arguments */
5139
0
        tmp_vol_obj.data = args->args.hard.curr_obj;
5140
0
    else
5141
        /* Use the VOL object passed in */
5142
0
        tmp_vol_obj.data = vol_obj->data;
5143
0
    tmp_vol_obj.connector = vol_obj->connector;
5144
5145
    /* Set wrapper info in API context */
5146
0
    if (H5VL_set_vol_wrapper(&tmp_vol_obj) < 0)
5147
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5148
0
    vol_wrapper_set = true;
5149
5150
    /* Call the corresponding internal VOL routine */
5151
0
    if (H5VL__link_create(args, vol_obj->data, loc_params, vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id,
5152
0
                          req) < 0)
5153
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "link create failed");
5154
5155
0
done:
5156
    /* Reset object wrapping info in API context */
5157
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5158
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5159
5160
0
    FUNC_LEAVE_NOAPI(ret_value)
5161
0
} /* end H5VL_link_create() */
5162
5163
/*-------------------------------------------------------------------------
5164
 * Function:    H5VLlink_create
5165
 *
5166
 * Purpose:     Creates a link
5167
 *
5168
 * Note:  The 'obj' parameter is allowed to be NULL
5169
 *
5170
 * Return:      Success:    Non-negative
5171
 *              Failure:    Negative
5172
 *
5173
 *-------------------------------------------------------------------------
5174
 */
5175
herr_t
5176
H5VLlink_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params,
5177
                hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req /*out*/)
5178
0
{
5179
0
    H5VL_connector_t *connector;           /* VOL connector */
5180
0
    herr_t            ret_value = SUCCEED; /* Return value */
5181
5182
0
    FUNC_ENTER_API_NOINIT
5183
5184
    /* Get connector pointer */
5185
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5186
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
5187
5188
    /* Call the corresponding internal VOL routine */
5189
0
    if (H5VL__link_create(args, obj, loc_params, connector->cls, lcpl_id, lapl_id, dxpl_id, req) < 0)
5190
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "unable to create link");
5191
5192
0
done:
5193
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5194
0
} /* end H5VLlink_create() */
5195
5196
/*-------------------------------------------------------------------------
5197
 * Function:  H5VL__link_copy
5198
 *
5199
 * Purpose: Copies a link from src to dst.
5200
 *
5201
 * Return:      Success:    Non-negative
5202
 *              Failure:    Negative
5203
 *
5204
 *-------------------------------------------------------------------------
5205
 */
5206
static herr_t
5207
H5VL__link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
5208
                const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id,
5209
                hid_t dxpl_id, void **req)
5210
0
{
5211
0
    herr_t ret_value = SUCCEED; /* Return value */
5212
5213
0
    FUNC_ENTER_PACKAGE
5214
5215
    /* Check if the corresponding VOL callback exists */
5216
0
    if (NULL == cls->link_cls.copy)
5217
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link copy' method");
5218
5219
    /* Prepare & restore library for user callback */
5220
0
    H5_BEFORE_USER_CB(FAIL)
5221
0
        {
5222
            /* Call the corresponding VOL callback */
5223
0
            ret_value = (cls->link_cls.copy)(src_obj, loc_params1, dst_obj, loc_params2, lcpl_id, lapl_id,
5224
0
                                             dxpl_id, req);
5225
0
        }
5226
0
    H5_AFTER_USER_CB(FAIL)
5227
0
    if (ret_value < 0)
5228
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "link copy failed");
5229
5230
0
done:
5231
0
    FUNC_LEAVE_NOAPI(ret_value)
5232
0
} /* end H5VL__link_copy() */
5233
5234
/*-------------------------------------------------------------------------
5235
 * Function:  H5VL_link_copy
5236
 *
5237
 * Purpose: Copies a link from src to dst.
5238
 *
5239
 * Return:      Success:    Non-negative
5240
 *              Failure:    Negative
5241
 *
5242
 *-------------------------------------------------------------------------
5243
 */
5244
herr_t
5245
H5VL_link_copy(const H5VL_object_t *src_vol_obj, const H5VL_loc_params_t *loc_params1,
5246
               const H5VL_object_t *dst_vol_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id,
5247
               hid_t lapl_id, hid_t dxpl_id, void **req)
5248
0
{
5249
0
    const H5VL_object_t *vol_obj;                   /* VOL object for object with data */
5250
0
    bool                 vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5251
0
    herr_t               ret_value       = SUCCEED; /* Return value */
5252
5253
0
    FUNC_ENTER_NOAPI(FAIL)
5254
5255
    /* Set wrapper info in API context */
5256
0
    vol_obj = (src_vol_obj->data ? src_vol_obj : dst_vol_obj);
5257
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5258
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5259
0
    vol_wrapper_set = true;
5260
5261
    /* Call the corresponding internal VOL routine */
5262
0
    if (H5VL__link_copy(src_vol_obj->data, loc_params1, (dst_vol_obj ? dst_vol_obj->data : NULL), loc_params2,
5263
0
                        vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, req) < 0)
5264
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "link copy failed");
5265
5266
0
done:
5267
    /* Reset object wrapping info in API context */
5268
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5269
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5270
5271
0
    FUNC_LEAVE_NOAPI(ret_value)
5272
0
} /* end H5VL_link_copy() */
5273
5274
/*-------------------------------------------------------------------------
5275
 * Function:    H5VLlink_copy
5276
 *
5277
 * Purpose:     Copies a link to a new location
5278
 *
5279
 * Note:  The 'src_obj' and 'dst_obj' parameters are allowed to be NULL
5280
 *
5281
 * Return:      Success:    Non-negative
5282
 *              Failure:    Negative
5283
 *
5284
 *-------------------------------------------------------------------------
5285
 */
5286
herr_t
5287
H5VLlink_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
5288
              const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id,
5289
              hid_t dxpl_id, void **req /*out*/)
5290
0
{
5291
0
    H5VL_connector_t *connector;           /* VOL connector */
5292
0
    herr_t            ret_value = SUCCEED; /* Return value */
5293
5294
0
    FUNC_ENTER_API_NOINIT
5295
5296
    /* Get connector pointer */
5297
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5298
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
5299
5300
    /* Call the corresponding internal VOL routine */
5301
0
    if (H5VL__link_copy(src_obj, loc_params1, dst_obj, loc_params2, connector->cls, lcpl_id, lapl_id, dxpl_id,
5302
0
                        req) < 0)
5303
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "unable to copy object");
5304
5305
0
done:
5306
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5307
0
} /* end H5VLlink_copy() */
5308
5309
/*-------------------------------------------------------------------------
5310
 * Function:  H5VL__link_move
5311
 *
5312
 * Purpose: Moves a link from src to dst.
5313
 *
5314
 * Return:      Success:    Non-negative
5315
 *              Failure:    Negative
5316
 *
5317
 *-------------------------------------------------------------------------
5318
 */
5319
static herr_t
5320
H5VL__link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
5321
                const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id,
5322
                hid_t dxpl_id, void **req)
5323
0
{
5324
0
    herr_t ret_value = SUCCEED; /* Return value */
5325
5326
0
    FUNC_ENTER_PACKAGE
5327
5328
    /* Check if the corresponding VOL callback exists */
5329
0
    if (NULL == cls->link_cls.move)
5330
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link move' method");
5331
5332
    /* Prepare & restore library for user callback */
5333
0
    H5_BEFORE_USER_CB(FAIL)
5334
0
        {
5335
            /* Call the corresponding VOL callback */
5336
0
            ret_value = (cls->link_cls.move)(src_obj, loc_params1, dst_obj, loc_params2, lcpl_id, lapl_id,
5337
0
                                             dxpl_id, req);
5338
0
        }
5339
0
    H5_AFTER_USER_CB(FAIL)
5340
0
    if (ret_value < 0)
5341
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTMOVE, FAIL, "link move failed");
5342
5343
0
done:
5344
0
    FUNC_LEAVE_NOAPI(ret_value)
5345
0
} /* end H5VL__link_move() */
5346
5347
/*-------------------------------------------------------------------------
5348
 * Function:  H5VL_link_move
5349
 *
5350
 * Purpose: Moves a link from src to dst.
5351
 *
5352
 * Return:      Success:    Non-negative
5353
 *              Failure:    Negative
5354
 *
5355
 *-------------------------------------------------------------------------
5356
 */
5357
herr_t
5358
H5VL_link_move(const H5VL_object_t *src_vol_obj, const H5VL_loc_params_t *loc_params1,
5359
               const H5VL_object_t *dst_vol_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id,
5360
               hid_t lapl_id, hid_t dxpl_id, void **req)
5361
0
{
5362
0
    const H5VL_object_t *vol_obj;                   /* VOL object for object with data */
5363
0
    bool                 vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5364
0
    herr_t               ret_value       = SUCCEED; /* Return value */
5365
5366
0
    FUNC_ENTER_NOAPI(FAIL)
5367
5368
    /* Sanity check */
5369
0
    assert(src_vol_obj);
5370
0
    assert(src_vol_obj->data);
5371
5372
    /* Set wrapper info in API context */
5373
0
    vol_obj = (src_vol_obj->data ? src_vol_obj : dst_vol_obj);
5374
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5375
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5376
0
    vol_wrapper_set = true;
5377
5378
    /* Call the corresponding internal VOL routine */
5379
0
    if (H5VL__link_move(src_vol_obj->data, loc_params1, (dst_vol_obj ? dst_vol_obj->data : NULL), loc_params2,
5380
0
                        vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, req) < 0)
5381
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTMOVE, FAIL, "link move failed");
5382
5383
0
done:
5384
    /* Reset object wrapping info in API context */
5385
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5386
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5387
5388
0
    FUNC_LEAVE_NOAPI(ret_value)
5389
0
} /* end H5VL_link_move() */
5390
5391
/*-------------------------------------------------------------------------
5392
 * Function:    H5VLlink_move
5393
 *
5394
 * Purpose:     Moves a link to another location
5395
 *
5396
 * Note:  The 'src_obj' and 'dst_obj' parameters are allowed to be NULL
5397
 *
5398
 * Return:      Success:    Non-negative
5399
 *              Failure:    Negative
5400
 *
5401
 *-------------------------------------------------------------------------
5402
 */
5403
herr_t
5404
H5VLlink_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
5405
              const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id,
5406
              hid_t dxpl_id, void **req /*out*/)
5407
0
{
5408
0
    H5VL_connector_t *connector;           /* VOL connector */
5409
0
    herr_t            ret_value = SUCCEED; /* Return value */
5410
5411
0
    FUNC_ENTER_API_NOINIT
5412
5413
    /* Get connector pointer */
5414
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5415
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
5416
5417
    /* Call the corresponding internal VOL routine */
5418
0
    if (H5VL__link_move(src_obj, loc_params1, dst_obj, loc_params2, connector->cls, lcpl_id, lapl_id, dxpl_id,
5419
0
                        req) < 0)
5420
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTMOVE, FAIL, "unable to move object");
5421
5422
0
done:
5423
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5424
0
} /* end H5VLlink_move() */
5425
5426
/*-------------------------------------------------------------------------
5427
 * Function:  H5VL__link_get
5428
 *
5429
 * Purpose: Get specific information about the link through the VOL
5430
 *
5431
 * Return:      Success:    Non-negative
5432
 *              Failure:    Negative
5433
 *
5434
 *-------------------------------------------------------------------------
5435
 */
5436
static herr_t
5437
H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
5438
               H5VL_link_get_args_t *args, hid_t dxpl_id, void **req)
5439
0
{
5440
0
    herr_t ret_value = SUCCEED; /* Return value */
5441
5442
0
    FUNC_ENTER_PACKAGE
5443
5444
    /* Check if the corresponding VOL callback exists */
5445
0
    if (NULL == cls->link_cls.get)
5446
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link get' method");
5447
5448
    /* Prepare & restore library for user callback */
5449
0
    H5_BEFORE_USER_CB(FAIL)
5450
0
        {
5451
            /* Call the corresponding VOL callback */
5452
0
            ret_value = (cls->link_cls.get)(obj, loc_params, args, dxpl_id, req);
5453
0
        }
5454
0
    H5_AFTER_USER_CB(FAIL)
5455
0
    if (ret_value < 0)
5456
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "link get failed");
5457
5458
0
done:
5459
0
    FUNC_LEAVE_NOAPI(ret_value)
5460
0
} /* end H5VL__link_get() */
5461
5462
/*-------------------------------------------------------------------------
5463
 * Function:  H5VL_link_get
5464
 *
5465
 * Purpose: Get specific information about the link through the VOL
5466
 *
5467
 * Return:      Success:    Non-negative
5468
 *              Failure:    Negative
5469
 *
5470
 *-------------------------------------------------------------------------
5471
 */
5472
herr_t
5473
H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args,
5474
              hid_t dxpl_id, void **req)
5475
0
{
5476
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5477
0
    herr_t ret_value       = SUCCEED; /* Return value */
5478
5479
0
    FUNC_ENTER_NOAPI(FAIL)
5480
5481
    /* Set wrapper info in API context */
5482
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5483
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5484
0
    vol_wrapper_set = true;
5485
5486
    /* Call the corresponding internal VOL routine */
5487
0
    if (H5VL__link_get(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0)
5488
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "link get failed");
5489
5490
0
done:
5491
    /* Reset object wrapping info in API context */
5492
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5493
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5494
5495
0
    FUNC_LEAVE_NOAPI(ret_value)
5496
0
} /* end H5VL_link_get() */
5497
5498
/*-------------------------------------------------------------------------
5499
 * Function:    H5VLlink_get
5500
 *
5501
 * Purpose:     Gets information about a link
5502
 *
5503
 * Return:      Success:    Non-negative
5504
 *              Failure:    Negative
5505
 *
5506
 *-------------------------------------------------------------------------
5507
 */
5508
herr_t
5509
H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_args_t *args,
5510
             hid_t dxpl_id, void **req /*out*/)
5511
0
{
5512
0
    H5VL_connector_t *connector;           /* VOL connector */
5513
0
    herr_t            ret_value = SUCCEED; /* Return value */
5514
5515
0
    FUNC_ENTER_API_NOINIT
5516
5517
    /* Check args and get connector pointer */
5518
0
    if (NULL == obj)
5519
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
5520
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5521
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
5522
5523
    /* Call the corresponding internal VOL routine */
5524
0
    if (H5VL__link_get(obj, loc_params, connector->cls, args, dxpl_id, req) < 0)
5525
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute link get callback");
5526
5527
0
done:
5528
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5529
0
} /* end H5VLlink_get() */
5530
5531
/*-------------------------------------------------------------------------
5532
 * Function:  H5VL__link_specific
5533
 *
5534
 * Purpose: Specific operation on links through the VOL
5535
 *
5536
 * Return:      Success:    Non-negative
5537
 *              Failure:    Negative
5538
 *
5539
 *-------------------------------------------------------------------------
5540
 */
5541
static herr_t
5542
H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
5543
                    H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req)
5544
0
{
5545
0
    herr_t ret_value = SUCCEED; /* Return value */
5546
5547
0
    FUNC_ENTER_PACKAGE
5548
5549
    /* Check if the corresponding VOL callback exists */
5550
0
    if (NULL == cls->link_cls.specific)
5551
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link specific' method");
5552
5553
    /* Prepare & restore library for user callback */
5554
0
    H5_BEFORE_USER_CB(FAIL)
5555
0
        {
5556
            /* Call the corresponding VOL callback */
5557
            /* (Must return value from callback, for iterators) */
5558
0
            ret_value = (cls->link_cls.specific)(obj, loc_params, args, dxpl_id, req);
5559
0
        }
5560
0
    H5_AFTER_USER_CB(FAIL)
5561
0
    if (ret_value < 0)
5562
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback");
5563
5564
0
done:
5565
0
    FUNC_LEAVE_NOAPI(ret_value)
5566
0
} /* end H5VL__link_specific() */
5567
5568
/*-------------------------------------------------------------------------
5569
 * Function:  H5VL_link_specific
5570
 *
5571
 * Purpose: Specific operation on links through the VOL
5572
 *
5573
 * Return:      Success:    Non-negative
5574
 *              Failure:    Negative
5575
 *
5576
 *-------------------------------------------------------------------------
5577
 */
5578
herr_t
5579
H5VL_link_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params,
5580
                   H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req)
5581
0
{
5582
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5583
0
    herr_t ret_value       = SUCCEED; /* Return value */
5584
5585
0
    FUNC_ENTER_NOAPI(FAIL)
5586
5587
    /* Set wrapper info in API context */
5588
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5589
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5590
0
    vol_wrapper_set = true;
5591
5592
    /* Call the corresponding internal VOL routine */
5593
    /* (Must return value from callback, for iterators) */
5594
0
    if ((ret_value =
5595
0
             H5VL__link_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req)) < 0)
5596
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback");
5597
5598
0
done:
5599
    /* Reset object wrapping info in API context */
5600
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5601
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5602
5603
0
    FUNC_LEAVE_NOAPI(ret_value)
5604
0
} /* end H5VL_link_specific() */
5605
5606
/*-------------------------------------------------------------------------
5607
 * Function:    H5VLlink_specific
5608
 *
5609
 * Purpose:     Performs a connector-specific operation on a link
5610
 *
5611
 * Return:      Success:    Non-negative
5612
 *              Failure:    Negative
5613
 *
5614
 *-------------------------------------------------------------------------
5615
 */
5616
herr_t
5617
H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id,
5618
                  H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req /*out*/)
5619
0
{
5620
0
    H5VL_connector_t *connector;           /* VOL connector */
5621
0
    herr_t            ret_value = SUCCEED; /* Return value */
5622
5623
0
    FUNC_ENTER_API_NOINIT
5624
5625
    /* Check args and get connector pointer */
5626
0
    if (NULL == obj)
5627
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
5628
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5629
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
5630
5631
    /* Call the corresponding internal VOL routine */
5632
    /* (Must return value from callback, for iterators) */
5633
0
    if ((ret_value = H5VL__link_specific(obj, loc_params, connector->cls, args, dxpl_id, req)) < 0)
5634
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback");
5635
5636
0
done:
5637
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5638
0
} /* end H5VLlink_specific() */
5639
5640
/*-------------------------------------------------------------------------
5641
 * Function:  H5VL__link_optional
5642
 *
5643
 * Purpose: Optional operation specific to connectors.
5644
 *
5645
 * Return:      Success:    Non-negative
5646
 *              Failure:    Negative
5647
 *
5648
 *-------------------------------------------------------------------------
5649
 */
5650
static herr_t
5651
H5VL__link_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
5652
                    H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
5653
0
{
5654
0
    herr_t ret_value = SUCCEED; /* Return value */
5655
5656
0
    FUNC_ENTER_PACKAGE
5657
5658
    /* Check if the corresponding VOL callback exists */
5659
0
    if (NULL == cls->link_cls.optional)
5660
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link optional' method");
5661
5662
    /* Prepare & restore library for user callback */
5663
0
    H5_BEFORE_USER_CB(FAIL)
5664
0
        {
5665
            /* Call the corresponding VOL callback */
5666
0
            ret_value = (cls->link_cls.optional)(obj, loc_params, args, dxpl_id, req);
5667
0
        }
5668
0
    H5_AFTER_USER_CB(FAIL)
5669
0
    if (ret_value < 0)
5670
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback");
5671
5672
0
done:
5673
0
    FUNC_LEAVE_NOAPI(ret_value)
5674
0
} /* end H5VL__link_optional() */
5675
5676
/*-------------------------------------------------------------------------
5677
 * Function:  H5VL_link_optional
5678
 *
5679
 * Purpose: Optional operation specific to connectors.
5680
 *
5681
 * Return:      Success:    Non-negative
5682
 *              Failure:    Negative
5683
 *
5684
 *-------------------------------------------------------------------------
5685
 */
5686
herr_t
5687
H5VL_link_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params,
5688
                   H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
5689
0
{
5690
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5691
0
    herr_t ret_value       = SUCCEED; /* Return value */
5692
5693
0
    FUNC_ENTER_NOAPI(FAIL)
5694
5695
    /* Set wrapper info in API context */
5696
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5697
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5698
0
    vol_wrapper_set = true;
5699
5700
    /* Call the corresponding internal VOL routine */
5701
0
    if (H5VL__link_optional(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0)
5702
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback");
5703
5704
0
done:
5705
    /* Reset object wrapping info in API context */
5706
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5707
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5708
5709
0
    FUNC_LEAVE_NOAPI(ret_value)
5710
0
} /* end H5VL_link_optional() */
5711
5712
/*-------------------------------------------------------------------------
5713
 * Function:    H5VLlink_optional
5714
 *
5715
 * Purpose:     Performs an optional connector-specific operation on a link
5716
 *
5717
 * Return:      Success:    Non-negative
5718
 *              Failure:    Negative
5719
 *
5720
 *-------------------------------------------------------------------------
5721
 */
5722
herr_t
5723
H5VLlink_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id,
5724
                  H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/)
5725
0
{
5726
0
    H5VL_connector_t *connector;           /* VOL connector */
5727
0
    herr_t            ret_value = SUCCEED; /* Return value */
5728
5729
0
    FUNC_ENTER_API_NOINIT
5730
5731
    /* Check args and get connector pointer */
5732
0
    if (NULL == obj)
5733
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
5734
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5735
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
5736
5737
    /* Call the corresponding internal VOL routine */
5738
0
    if (H5VL__link_optional(obj, loc_params, connector->cls, args, dxpl_id, req) < 0)
5739
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback");
5740
5741
0
done:
5742
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5743
0
} /* end H5VLlink_optional() */
5744
5745
/*-------------------------------------------------------------------------
5746
 * Function:    H5VLlink_optional_op
5747
 *
5748
 * Purpose:     Performs an optional connector-specific operation on a link
5749
 *
5750
 * Return:      Success:    Non-negative
5751
 *              Failure:    Negative
5752
 *
5753
 *-------------------------------------------------------------------------
5754
 */
5755
herr_t
5756
H5VLlink_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
5757
                     const char *name, hid_t lapl_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id)
5758
0
{
5759
0
    H5VL_object_t    *vol_obj = NULL;              /* Object for loc_id */
5760
0
    H5VL_loc_params_t loc_params;                  /* Location parameters for object access */
5761
0
    void             *token     = NULL;            /* Request token for async operation        */
5762
0
    void            **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
5763
0
    bool              vol_wrapper_set = false;     /* Whether the VOL object wrapping context was set up */
5764
0
    herr_t            ret_value       = SUCCEED;   /* Return value */
5765
5766
0
    FUNC_ENTER_API(FAIL)
5767
5768
    /* Check arguments */
5769
    /* name is verified in H5VL_setup_name_args() */
5770
5771
    /* Set up object access arguments */
5772
0
    if (H5VL_setup_name_args(loc_id, name, false, lapl_id, &vol_obj, &loc_params) < 0)
5773
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set link access arguments");
5774
5775
    /* Set up request token pointer for asynchronous operation */
5776
0
    if (H5ES_NONE != es_id)
5777
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
5778
5779
    /* Set wrapper info in API context */
5780
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5781
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5782
0
    vol_wrapper_set = true;
5783
5784
    /* Call the corresponding internal VOL routine */
5785
0
    if (H5VL__link_optional(vol_obj->data, &loc_params, vol_obj->connector->cls, args, dxpl_id, token_ptr) <
5786
0
        0)
5787
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback");
5788
5789
    /* If a token was created, add the token to the event set */
5790
0
    if (NULL != token)
5791
        /* clang-format off */
5792
0
        if (H5ES_insert(es_id, vol_obj->connector, token, H5ARG_TRACE9(__func__, "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, es_id)) < 0)
5793
            /* clang-format on */
5794
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set");
5795
5796
0
done:
5797
    /* Reset object wrapping info in API context */
5798
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5799
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5800
5801
0
    FUNC_LEAVE_API(ret_value)
5802
0
} /* end H5VLlink_optional_op() */
5803
5804
/*-------------------------------------------------------------------------
5805
 * Function:  H5VL__object_open
5806
 *
5807
 * Purpose: Opens a object through the VOL
5808
 *
5809
 * Return:      Success: Pointer to the object
5810
 *    Failure: NULL
5811
 *
5812
 *-------------------------------------------------------------------------
5813
 */
5814
static void *
5815
H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls,
5816
                  H5I_type_t *opened_type, hid_t dxpl_id, void **req)
5817
0
{
5818
0
    void *ret_value = NULL; /* Return value */
5819
5820
0
    FUNC_ENTER_PACKAGE
5821
5822
    /* Check if the corresponding VOL callback exists */
5823
0
    if (NULL == cls->object_cls.open)
5824
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'object open' method");
5825
5826
    /* Prepare & restore library for user callback */
5827
0
    H5_BEFORE_USER_CB(NULL)
5828
0
        {
5829
            /* Call the corresponding VOL callback */
5830
0
            ret_value = (cls->object_cls.open)(obj, params, opened_type, dxpl_id, req);
5831
0
        }
5832
0
    H5_AFTER_USER_CB(NULL)
5833
0
    if (NULL == ret_value)
5834
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "object open failed");
5835
5836
0
done:
5837
0
    FUNC_LEAVE_NOAPI(ret_value)
5838
0
} /* end H5VL__object_open() */
5839
5840
/*-------------------------------------------------------------------------
5841
 * Function:  H5VL_object_open
5842
 *
5843
 * Purpose: Opens a object through the VOL
5844
 *
5845
 * Return:      Success: Pointer to the object
5846
 *    Failure: NULL
5847
 *
5848
 *-------------------------------------------------------------------------
5849
 */
5850
void *
5851
H5VL_object_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *params, H5I_type_t *opened_type,
5852
                 hid_t dxpl_id, void **req)
5853
0
{
5854
0
    bool  vol_wrapper_set = false; /* Whether the VOL object wrapping context was set up */
5855
0
    void *ret_value       = NULL;  /* Return value */
5856
5857
0
    FUNC_ENTER_NOAPI(NULL)
5858
5859
    /* Set wrapper info in API context */
5860
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
5861
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, NULL, "can't set VOL wrapper info");
5862
0
    vol_wrapper_set = true;
5863
5864
    /* Call the corresponding internal VOL routine */
5865
0
    if (NULL == (ret_value = H5VL__object_open(vol_obj->data, params, vol_obj->connector->cls, opened_type,
5866
0
                                               dxpl_id, req)))
5867
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "object open failed");
5868
5869
0
done:
5870
    /* Reset object wrapping info in API context */
5871
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5872
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, NULL, "can't reset VOL wrapper info");
5873
5874
0
    FUNC_LEAVE_NOAPI(ret_value)
5875
0
} /* end H5VL_object_open() */
5876
5877
/*-------------------------------------------------------------------------
5878
 * Function:    H5VLobject_open
5879
 *
5880
 * Purpose:     Opens an object
5881
 *
5882
 * Return:      Success:    Pointer to the object
5883
 *              Failure:    NULL
5884
 *
5885
 *-------------------------------------------------------------------------
5886
 */
5887
void *
5888
H5VLobject_open(void *obj, const H5VL_loc_params_t *params, hid_t connector_id, H5I_type_t *opened_type,
5889
                hid_t dxpl_id, void **req /*out*/)
5890
0
{
5891
0
    H5VL_connector_t *connector;        /* VOL connector */
5892
0
    void             *ret_value = NULL; /* Return value */
5893
5894
0
    FUNC_ENTER_API_NOINIT
5895
5896
    /* Check args and get connector pointer */
5897
0
    if (NULL == obj)
5898
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object");
5899
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
5900
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID");
5901
5902
    /* Call the corresponding internal VOL routine */
5903
0
    if (NULL == (ret_value = H5VL__object_open(obj, params, connector->cls, opened_type, dxpl_id, req)))
5904
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "unable to open object");
5905
5906
0
done:
5907
0
    FUNC_LEAVE_API_NOINIT(ret_value)
5908
0
} /* end H5VLobject_open() */
5909
5910
/*-------------------------------------------------------------------------
5911
 * Function:  H5VL__object_copy
5912
 *
5913
 * Purpose: Copies an object to another destination through the VOL
5914
 *
5915
 * Return:      Success:    Non-negative
5916
 *              Failure:    Negative
5917
 *
5918
 *-------------------------------------------------------------------------
5919
 */
5920
static herr_t
5921
H5VL__object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name, void *dst_obj,
5922
                  const H5VL_loc_params_t *dst_loc_params, const char *dst_name, const H5VL_class_t *cls,
5923
                  hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req)
5924
0
{
5925
0
    herr_t ret_value = SUCCEED; /* Return value */
5926
5927
0
    FUNC_ENTER_PACKAGE
5928
5929
    /* Check if the corresponding VOL callback exists */
5930
0
    if (NULL == cls->object_cls.copy)
5931
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object copy' method");
5932
5933
    /* Prepare & restore library for user callback */
5934
0
    H5_BEFORE_USER_CB(FAIL)
5935
0
        {
5936
            /* Call the corresponding VOL callback */
5937
0
            ret_value = (cls->object_cls.copy)(src_obj, src_loc_params, src_name, dst_obj, dst_loc_params,
5938
0
                                               dst_name, ocpypl_id, lcpl_id, dxpl_id, req);
5939
0
        }
5940
0
    H5_AFTER_USER_CB(FAIL)
5941
0
    if (ret_value < 0)
5942
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "object copy failed");
5943
5944
0
done:
5945
0
    FUNC_LEAVE_NOAPI(ret_value)
5946
0
} /* end H5VL__object_copy() */
5947
5948
/*-------------------------------------------------------------------------
5949
 * Function:  H5VL_object_copy
5950
 *
5951
 * Purpose: Copies an object to another destination through the VOL
5952
 *
5953
 * Return:      Success:    Non-negative
5954
 *              Failure:    Negative
5955
 *
5956
 *-------------------------------------------------------------------------
5957
 */
5958
herr_t
5959
H5VL_object_copy(const H5VL_object_t *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name,
5960
                 const H5VL_object_t *dst_obj, const H5VL_loc_params_t *dst_loc_params, const char *dst_name,
5961
                 hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req)
5962
0
{
5963
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
5964
0
    herr_t ret_value       = SUCCEED; /* Return value */
5965
5966
0
    FUNC_ENTER_NOAPI(FAIL)
5967
5968
    /* Make sure that the VOL connectors are the same */
5969
0
    if (src_obj->connector->cls->value != dst_obj->connector->cls->value)
5970
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
5971
0
                    "objects are accessed through different VOL connectors and can't be copied");
5972
5973
    /* Set wrapper info in API context */
5974
0
    if (H5VL_set_vol_wrapper(src_obj) < 0)
5975
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
5976
0
    vol_wrapper_set = true;
5977
5978
    /* Call the corresponding internal VOL routine */
5979
0
    if (H5VL__object_copy(src_obj->data, src_loc_params, src_name, dst_obj->data, dst_loc_params, dst_name,
5980
0
                          src_obj->connector->cls, ocpypl_id, lcpl_id, dxpl_id, req) < 0)
5981
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "object copy failed");
5982
5983
0
done:
5984
    /* Reset object wrapping info in API context */
5985
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
5986
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
5987
5988
0
    FUNC_LEAVE_NOAPI(ret_value)
5989
0
} /* end H5VL_object_copy() */
5990
5991
/*-------------------------------------------------------------------------
5992
 * Function:    H5VLobject_copy
5993
 *
5994
 * Purpose:     Copies an object to another location
5995
 *
5996
 * Return:      Success:    Non-negative
5997
 *              Failure:    Negative
5998
 *
5999
 *-------------------------------------------------------------------------
6000
 */
6001
herr_t
6002
H5VLobject_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name, void *dst_obj,
6003
                const H5VL_loc_params_t *dst_loc_params, const char *dst_name, hid_t connector_id,
6004
                hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req /*out*/)
6005
0
{
6006
0
    H5VL_connector_t *connector;           /* VOL connector */
6007
0
    herr_t            ret_value = SUCCEED; /* Return value */
6008
6009
0
    FUNC_ENTER_API_NOINIT
6010
6011
    /* Check args and get connector pointers */
6012
0
    if (NULL == src_obj || NULL == dst_obj)
6013
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
6014
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6015
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6016
6017
    /* Call the corresponding internal VOL routine */
6018
0
    if (H5VL__object_copy(src_obj, src_loc_params, src_name, dst_obj, dst_loc_params, dst_name,
6019
0
                          connector->cls, ocpypl_id, lcpl_id, dxpl_id, req) < 0)
6020
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "unable to copy object");
6021
6022
0
done:
6023
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6024
0
} /* end H5VLobject_copy() */
6025
6026
/*-------------------------------------------------------------------------
6027
 * Function:  H5VL__object_get
6028
 *
6029
 * Purpose: Get specific information about the object through the VOL
6030
 *
6031
 * Return:      Success:    Non-negative
6032
 *              Failure:    Negative
6033
 *
6034
 *-------------------------------------------------------------------------
6035
 */
6036
static herr_t
6037
H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
6038
                 H5VL_object_get_args_t *args, hid_t dxpl_id, void **req)
6039
0
{
6040
0
    herr_t ret_value = SUCCEED; /* Return value */
6041
6042
0
    FUNC_ENTER_PACKAGE
6043
6044
    /* Check if the corresponding VOL callback exists */
6045
0
    if (NULL == cls->object_cls.get)
6046
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object get' method");
6047
6048
    /* Prepare & restore library for user callback */
6049
0
    H5_BEFORE_USER_CB(FAIL)
6050
0
        {
6051
            /* Call the corresponding VOL callback */
6052
0
            ret_value = (cls->object_cls.get)(obj, loc_params, args, dxpl_id, req);
6053
0
        }
6054
0
    H5_AFTER_USER_CB(FAIL)
6055
0
    if (ret_value < 0)
6056
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed");
6057
6058
0
done:
6059
0
    FUNC_LEAVE_NOAPI(ret_value)
6060
0
} /* end H5VL__object_get() */
6061
6062
/*-------------------------------------------------------------------------
6063
 * Function:  H5VL_object_get
6064
 *
6065
 * Purpose: Get specific information about the object through the VOL
6066
 *
6067
 * Return:      Success:    Non-negative
6068
 *              Failure:    Negative
6069
 *
6070
 *-------------------------------------------------------------------------
6071
 */
6072
herr_t
6073
H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params,
6074
                H5VL_object_get_args_t *args, hid_t dxpl_id, void **req)
6075
0
{
6076
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
6077
0
    herr_t ret_value       = SUCCEED; /* Return value */
6078
6079
0
    FUNC_ENTER_NOAPI(FAIL)
6080
6081
    /* Set wrapper info in API context */
6082
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6083
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6084
0
    vol_wrapper_set = true;
6085
6086
    /* Call the corresponding internal VOL routine */
6087
0
    if (H5VL__object_get(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0)
6088
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed");
6089
6090
0
done:
6091
    /* Reset object wrapping info in API context */
6092
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6093
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6094
6095
0
    FUNC_LEAVE_NOAPI(ret_value)
6096
0
} /* end H5VL_object_get() */
6097
6098
/*-------------------------------------------------------------------------
6099
 * Function:    H5VLobject_get
6100
 *
6101
 * Purpose:     Gets information about an object
6102
 *
6103
 * Return:      Success:    Non-negative
6104
 *              Failure:    Negative
6105
 *
6106
 *-------------------------------------------------------------------------
6107
 */
6108
herr_t
6109
H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id,
6110
               H5VL_object_get_args_t *args, hid_t dxpl_id, void **req /*out*/)
6111
0
{
6112
0
    H5VL_connector_t *connector;           /* VOL connector */
6113
0
    herr_t            ret_value = SUCCEED; /* Return value */
6114
6115
0
    FUNC_ENTER_API_NOINIT
6116
6117
    /* Check args and get connector pointer */
6118
0
    if (NULL == obj)
6119
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
6120
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6121
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6122
6123
    /* Call the corresponding internal VOL routine */
6124
0
    if (H5VL__object_get(obj, loc_params, connector->cls, args, dxpl_id, req) < 0)
6125
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute object get callback");
6126
6127
0
done:
6128
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6129
0
} /* end H5VLobject_get() */
6130
6131
/*-------------------------------------------------------------------------
6132
 * Function:  H5VL__object_specific
6133
 *
6134
 * Purpose: Specific operation on objects through the VOL
6135
 *
6136
 * Return:      Success:    Non-negative
6137
 *              Failure:    Negative
6138
 *
6139
 *-------------------------------------------------------------------------
6140
 */
6141
static herr_t
6142
H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
6143
                      H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req)
6144
0
{
6145
0
    herr_t ret_value = SUCCEED; /* Return value */
6146
6147
0
    FUNC_ENTER_PACKAGE
6148
6149
    /* Check if the corresponding VOL callback exists */
6150
0
    if (NULL == cls->object_cls.specific)
6151
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object specific' method");
6152
6153
    /* Prepare & restore library for user callback */
6154
0
    H5_BEFORE_USER_CB(FAIL)
6155
0
        {
6156
            /* Call the corresponding VOL callback */
6157
            /* (Must return value from callback, for iterators) */
6158
0
            ret_value = (cls->object_cls.specific)(obj, loc_params, args, dxpl_id, req);
6159
0
        }
6160
0
    H5_AFTER_USER_CB(FAIL)
6161
0
    if (ret_value < 0)
6162
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "object specific failed");
6163
6164
0
done:
6165
0
    FUNC_LEAVE_NOAPI(ret_value)
6166
0
} /* end H5VL__object_specific() */
6167
6168
/*-------------------------------------------------------------------------
6169
 * Function:  H5VL_object_specific
6170
 *
6171
 * Purpose: Specific operation on objects through the VOL
6172
 *
6173
 * Return:      Success:    Non-negative
6174
 *              Failure:    Negative
6175
 *
6176
 *-------------------------------------------------------------------------
6177
 */
6178
herr_t
6179
H5VL_object_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params,
6180
                     H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req)
6181
0
{
6182
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
6183
0
    herr_t ret_value       = SUCCEED; /* Return value */
6184
6185
0
    FUNC_ENTER_NOAPI(FAIL)
6186
6187
    /* Set wrapper info in API context */
6188
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6189
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6190
0
    vol_wrapper_set = true;
6191
6192
    /* Call the corresponding internal VOL routine */
6193
    /* (Must return value from callback, for iterators) */
6194
0
    if ((ret_value = H5VL__object_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id,
6195
0
                                           req)) < 0)
6196
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "object specific failed");
6197
6198
0
done:
6199
    /* Reset object wrapping info in API context */
6200
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6201
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6202
6203
0
    FUNC_LEAVE_NOAPI(ret_value)
6204
0
} /* end H5VL_object_specific() */
6205
6206
/*-------------------------------------------------------------------------
6207
 * Function:    H5VLobject_specific
6208
 *
6209
 * Purpose:     Performs a connector-specific operation on an object
6210
 *
6211
 * Return:      Success:    Non-negative
6212
 *              Failure:    Negative
6213
 *
6214
 *-------------------------------------------------------------------------
6215
 */
6216
herr_t
6217
H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id,
6218
                    H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req /*out*/)
6219
0
{
6220
0
    H5VL_connector_t *connector;           /* VOL connector */
6221
0
    herr_t            ret_value = SUCCEED; /* Return value */
6222
6223
0
    FUNC_ENTER_API_NOINIT
6224
6225
    /* Check args and get connector pointer */
6226
0
    if (NULL == obj)
6227
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
6228
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6229
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6230
6231
    /* Call the corresponding internal VOL routine */
6232
    /* (Must return value from callback, for iterators) */
6233
0
    if ((ret_value = H5VL__object_specific(obj, loc_params, connector->cls, args, dxpl_id, req)) < 0)
6234
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute object specific callback");
6235
6236
0
done:
6237
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6238
0
} /* end H5VLobject_specific() */
6239
6240
/*-------------------------------------------------------------------------
6241
 * Function:  H5VL__object_optional
6242
 *
6243
 * Purpose: Optional operation specific to connectors.
6244
 *
6245
 * Return:      Success:    Non-negative
6246
 *              Failure:    Negative
6247
 *
6248
 *-------------------------------------------------------------------------
6249
 */
6250
static herr_t
6251
H5VL__object_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
6252
                      H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
6253
0
{
6254
0
    herr_t ret_value = SUCCEED; /* Return value */
6255
6256
0
    FUNC_ENTER_PACKAGE
6257
6258
    /* Check if the corresponding VOL callback exists */
6259
0
    if (NULL == cls->object_cls.optional)
6260
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object optional' method");
6261
6262
    /* Prepare & restore library for user callback */
6263
0
    H5_BEFORE_USER_CB(FAIL)
6264
0
        {
6265
            /* Call the corresponding VOL callback */
6266
0
            ret_value = (cls->object_cls.optional)(obj, loc_params, args, dxpl_id, req);
6267
0
        }
6268
0
    H5_AFTER_USER_CB(FAIL)
6269
0
    if (ret_value < 0)
6270
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback");
6271
6272
0
done:
6273
0
    FUNC_LEAVE_NOAPI(ret_value)
6274
0
} /* end H5VL__object_optional() */
6275
6276
/*-------------------------------------------------------------------------
6277
 * Function:  H5VL_object_optional
6278
 *
6279
 * Purpose: Optional operation specific to connectors.
6280
 *
6281
 * Return:      Success:    Non-negative
6282
 *              Failure:    Negative
6283
 *
6284
 *-------------------------------------------------------------------------
6285
 */
6286
herr_t
6287
H5VL_object_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params,
6288
                     H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
6289
0
{
6290
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
6291
0
    herr_t ret_value       = SUCCEED; /* Return value */
6292
6293
0
    FUNC_ENTER_NOAPI(FAIL)
6294
6295
    /* Set wrapper info in API context */
6296
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6297
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6298
0
    vol_wrapper_set = true;
6299
6300
    /* Call the corresponding internal VOL routine */
6301
0
    if (H5VL__object_optional(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0)
6302
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback");
6303
6304
0
done:
6305
    /* Reset object wrapping info in API context */
6306
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6307
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6308
6309
0
    FUNC_LEAVE_NOAPI(ret_value)
6310
0
} /* end H5VL_object_optional() */
6311
6312
/*-------------------------------------------------------------------------
6313
 * Function:    H5VLobject_optional
6314
 *
6315
 * Purpose:     Performs an optional connector-specific operation on an object
6316
 *
6317
 * Return:      Success:    Non-negative
6318
 *              Failure:    Negative
6319
 *
6320
 *-------------------------------------------------------------------------
6321
 */
6322
herr_t
6323
H5VLobject_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id,
6324
                    H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/)
6325
0
{
6326
0
    H5VL_connector_t *connector;           /* VOL connector */
6327
0
    herr_t            ret_value = SUCCEED; /* Return value */
6328
6329
0
    FUNC_ENTER_API_NOINIT
6330
6331
    /* Check args and get connector pointer */
6332
0
    if (NULL == obj)
6333
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
6334
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6335
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6336
6337
    /* Call the corresponding internal VOL routine */
6338
0
    if (H5VL__object_optional(obj, loc_params, connector->cls, args, dxpl_id, req) < 0)
6339
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback");
6340
6341
0
done:
6342
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6343
0
} /* end H5VLobject_optional() */
6344
6345
/*-------------------------------------------------------------------------
6346
 * Function:    H5VLobject_optional_op
6347
 *
6348
 * Purpose:     Performs an optional connector-specific operation on an object
6349
 *
6350
 * Return:      Success:    Non-negative
6351
 *              Failure:    Negative
6352
 *
6353
 *-------------------------------------------------------------------------
6354
 */
6355
herr_t
6356
H5VLobject_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
6357
                       const char *name, hid_t lapl_id, H5VL_optional_args_t *args, hid_t dxpl_id,
6358
                       hid_t es_id)
6359
0
{
6360
0
    H5VL_object_t    *vol_obj = NULL;              /* Object for loc_id */
6361
0
    H5VL_loc_params_t loc_params;                  /* Location parameters for object access */
6362
0
    void             *token     = NULL;            /* Request token for async operation        */
6363
0
    void            **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
6364
0
    bool              vol_wrapper_set = false;     /* Whether the VOL object wrapping context was set up */
6365
0
    herr_t            ret_value       = SUCCEED;   /* Return value */
6366
6367
0
    FUNC_ENTER_API(FAIL)
6368
6369
    /* Check arguments */
6370
    /* name is verified in H5VL_setup_name_args() */
6371
6372
    /* Set up object access arguments */
6373
0
    if (H5VL_setup_name_args(loc_id, name, false, lapl_id, &vol_obj, &loc_params) < 0)
6374
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set link access arguments");
6375
6376
    /* Set up request token pointer for asynchronous operation */
6377
0
    if (H5ES_NONE != es_id)
6378
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
6379
6380
    /* Set wrapper info in API context */
6381
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6382
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6383
0
    vol_wrapper_set = true;
6384
6385
    /* Call the corresponding internal VOL routine */
6386
0
    if (H5VL__object_optional(vol_obj->data, &loc_params, vol_obj->connector->cls, args, dxpl_id, token_ptr) <
6387
0
        0)
6388
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback");
6389
6390
    /* If a token was created, add the token to the event set */
6391
0
    if (NULL != token)
6392
        /* clang-format off */
6393
0
        if (H5ES_insert(es_id, vol_obj->connector, token, H5ARG_TRACE9(__func__, "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, es_id)) < 0)
6394
            /* clang-format on */
6395
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set");
6396
6397
0
done:
6398
    /* Reset object wrapping info in API context */
6399
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6400
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6401
6402
0
    FUNC_LEAVE_API(ret_value)
6403
0
} /* end H5VLobject_optional_op() */
6404
6405
/*-------------------------------------------------------------------------
6406
 * Function:  H5VL__introspect_get_conn_cls
6407
 *
6408
 * Purpose:     Calls the connector-specific callback to query the connector
6409
 *              class.
6410
 *
6411
 * Return:      Success:    Non-negative
6412
 *              Failure:    Negative
6413
 *
6414
 *-------------------------------------------------------------------------
6415
 */
6416
static herr_t
6417
H5VL__introspect_get_conn_cls(void *obj, const H5VL_class_t *cls, H5VL_get_conn_lvl_t lvl,
6418
                              const H5VL_class_t **conn_cls)
6419
0
{
6420
0
    herr_t ret_value = SUCCEED; /* Return value */
6421
6422
0
    FUNC_ENTER_PACKAGE
6423
6424
    /* Sanity check */
6425
0
    assert(obj);
6426
0
    assert(cls);
6427
0
    assert(lvl >= H5VL_GET_CONN_LVL_CURR && lvl <= H5VL_GET_CONN_LVL_TERM);
6428
0
    assert(conn_cls);
6429
6430
    /* Check if the corresponding VOL callback exists */
6431
0
    if (NULL == cls->introspect_cls.get_conn_cls)
6432
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'get_conn_cls' method");
6433
6434
    /* Prepare & restore library for user callback */
6435
0
    H5_BEFORE_USER_CB(FAIL)
6436
0
        {
6437
            /* Call the corresponding VOL callback */
6438
0
            ret_value = (cls->introspect_cls.get_conn_cls)(obj, lvl, conn_cls);
6439
0
        }
6440
0
    H5_AFTER_USER_CB(FAIL)
6441
0
    if (ret_value < 0)
6442
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector class");
6443
6444
0
done:
6445
0
    FUNC_LEAVE_NOAPI(ret_value)
6446
0
} /* end H5VL__introspect_get_conn_cls() */
6447
6448
/*-------------------------------------------------------------------------
6449
 * Function:    H5VL_introspect_get_conn_cls
6450
 *
6451
 * Purpose:     Calls the connector-specific callback to query the connector
6452
 *              class.
6453
 *
6454
 * Return:      Success:    Non-negative
6455
 *              Failure:    Negative
6456
 *
6457
 *-------------------------------------------------------------------------
6458
 */
6459
herr_t
6460
H5VL_introspect_get_conn_cls(const H5VL_object_t *vol_obj, H5VL_get_conn_lvl_t lvl,
6461
                             const H5VL_class_t **conn_cls)
6462
0
{
6463
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
6464
0
    herr_t ret_value       = SUCCEED; /* Return value */
6465
6466
0
    FUNC_ENTER_NOAPI(FAIL)
6467
6468
    /* Set wrapper info in API context */
6469
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6470
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6471
0
    vol_wrapper_set = true;
6472
6473
    /* Call the corresponding internal VOL routine */
6474
0
    if (H5VL__introspect_get_conn_cls(vol_obj->data, vol_obj->connector->cls, lvl, conn_cls) < 0)
6475
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector class");
6476
6477
0
done:
6478
    /* Reset object wrapping info in API context */
6479
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6480
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6481
6482
0
    FUNC_LEAVE_NOAPI(ret_value)
6483
0
} /* end H5VL_introspect_get_conn_cls() */
6484
6485
/*-------------------------------------------------------------------------
6486
 * Function:    H5VLintrospect_get_conn_cls
6487
 *
6488
 * Purpose:     Calls the connector-specific callback to query the connector
6489
 *              class.
6490
 *
6491
 * Return:      Success:    Non-negative
6492
 *              Failure:    Negative
6493
 *
6494
 *-------------------------------------------------------------------------
6495
 */
6496
herr_t
6497
H5VLintrospect_get_conn_cls(void *obj, hid_t connector_id, H5VL_get_conn_lvl_t lvl,
6498
                            const H5VL_class_t **conn_cls /*out*/)
6499
0
{
6500
0
    H5VL_connector_t *connector;           /* VOL connector */
6501
0
    herr_t            ret_value = SUCCEED; /* Return value */
6502
6503
0
    FUNC_ENTER_API_NOINIT
6504
6505
    /* Check args */
6506
0
    if (NULL == obj)
6507
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL obj pointer");
6508
0
    if (NULL == conn_cls)
6509
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL conn_cls pointer");
6510
6511
    /* Get connector pointer */
6512
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6513
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6514
6515
    /* Call the corresponding internal VOL routine */
6516
0
    if (H5VL__introspect_get_conn_cls(obj, connector->cls, lvl, conn_cls) < 0)
6517
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector class");
6518
6519
0
done:
6520
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6521
0
} /* end H5VLintrospect_get_conn_cls() */
6522
6523
/*-------------------------------------------------------------------------
6524
 * Function:  H5VL_introspect_get_cap_flags
6525
 *
6526
 * Purpose:     Calls the connector-specific callback to query the connector's
6527
 *              capability flags.
6528
 *
6529
 * Return:      Success:    Non-negative
6530
 *              Failure:    Negative
6531
 *
6532
 *-------------------------------------------------------------------------
6533
 */
6534
herr_t
6535
H5VL_introspect_get_cap_flags(const void *info, const H5VL_class_t *cls, uint64_t *cap_flags)
6536
0
{
6537
0
    herr_t ret_value = SUCCEED; /* Return value */
6538
6539
0
    FUNC_ENTER_NOAPI(FAIL)
6540
6541
    /* Sanity check */
6542
0
    assert(cls);
6543
0
    assert(cap_flags);
6544
6545
    /* Check if the corresponding VOL callback exists */
6546
0
    if (NULL == cls->introspect_cls.get_cap_flags)
6547
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'get_cap_flags' method");
6548
6549
    /* Prepare & restore library for user callback */
6550
0
    H5_BEFORE_USER_CB(FAIL)
6551
0
        {
6552
            /* Call the corresponding VOL callback */
6553
0
            ret_value = (cls->introspect_cls.get_cap_flags)(info, cap_flags);
6554
0
        }
6555
0
    H5_AFTER_USER_CB(FAIL)
6556
0
    if (ret_value < 0)
6557
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector capability flags");
6558
6559
0
done:
6560
0
    FUNC_LEAVE_NOAPI(ret_value)
6561
0
} /* end H5VL_introspect_get_cap_flags() */
6562
6563
/*-------------------------------------------------------------------------
6564
 * Function:    H5VLintrospect_get_cap_flags
6565
 *
6566
 * Purpose:     Calls the connector-specific callback to query the connector's
6567
 *              capability flags.
6568
 *
6569
 * Return:      Success:    Non-negative
6570
 *              Failure:    Negative
6571
 *
6572
 *-------------------------------------------------------------------------
6573
 */
6574
herr_t
6575
H5VLintrospect_get_cap_flags(const void *info, hid_t connector_id, uint64_t *cap_flags /*out*/)
6576
0
{
6577
0
    H5VL_connector_t *connector;           /* VOL connector */
6578
0
    herr_t            ret_value = SUCCEED; /* Return value */
6579
6580
0
    FUNC_ENTER_API_NOINIT
6581
6582
    /* Check args */
6583
0
    if (NULL == cap_flags)
6584
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL conn_cls pointer");
6585
6586
    /* Get connector pointer */
6587
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6588
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6589
6590
    /* Call the corresponding internal VOL routine */
6591
0
    if (H5VL_introspect_get_cap_flags(info, connector->cls, cap_flags) < 0)
6592
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector's capability flags");
6593
6594
0
done:
6595
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6596
0
} /* end H5VLintrospect_get_cap_flags() */
6597
6598
/*-------------------------------------------------------------------------
6599
 * Function:  H5VL__introspect_opt_query
6600
 *
6601
 * Purpose:     Calls the connector-specific callback to query if an optional
6602
 *              operation is supported.
6603
 *
6604
 * Return:      Success:    Non-negative
6605
 *              Failure:    Negative
6606
 *
6607
 *-------------------------------------------------------------------------
6608
 */
6609
static herr_t
6610
H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t subcls, int opt_type,
6611
                           uint64_t *flags)
6612
673
{
6613
673
    herr_t ret_value = SUCCEED; /* Return value */
6614
6615
673
    FUNC_ENTER_PACKAGE
6616
6617
    /* Check if the corresponding VOL callback exists */
6618
673
    if (NULL == cls->introspect_cls.opt_query)
6619
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'opt_query' method");
6620
6621
    /* Prepare & restore library for user callback */
6622
673
    H5_BEFORE_USER_CB(FAIL)
6623
673
        {
6624
            /* Call the corresponding VOL callback */
6625
673
            ret_value = (cls->introspect_cls.opt_query)(obj, subcls, opt_type, flags);
6626
673
        }
6627
673
    H5_AFTER_USER_CB(FAIL)
6628
673
    if (ret_value < 0)
6629
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query optional operation support");
6630
6631
673
done:
6632
673
    FUNC_LEAVE_NOAPI(ret_value)
6633
673
} /* end H5VL__introspect_opt_query() */
6634
6635
/*-------------------------------------------------------------------------
6636
 * Function:    H5VL_introspect_opt_query
6637
 *
6638
 * Purpose:     Calls the connector-specific callback to query if an optional
6639
 *              operation is supported.
6640
 *
6641
 * Return:      Success:    Non-negative
6642
 *              Failure:    Negative
6643
 *
6644
 *-------------------------------------------------------------------------
6645
 */
6646
herr_t
6647
H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subclass_t subcls, int opt_type, uint64_t *flags)
6648
673
{
6649
673
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
6650
673
    herr_t ret_value       = SUCCEED; /* Return value */
6651
6652
673
    FUNC_ENTER_NOAPI(FAIL)
6653
6654
    /* Set wrapper info in API context */
6655
673
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6656
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6657
673
    vol_wrapper_set = true;
6658
6659
    /* Call the corresponding internal VOL routine */
6660
673
    if (H5VL__introspect_opt_query(vol_obj->data, vol_obj->connector->cls, subcls, opt_type, flags) < 0)
6661
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query optional operation support");
6662
6663
673
done:
6664
    /* Reset object wrapping info in API context */
6665
673
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6666
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6667
6668
673
    FUNC_LEAVE_NOAPI(ret_value)
6669
673
} /* end H5VL_introspect_opt_query() */
6670
6671
/*-------------------------------------------------------------------------
6672
 * Function:    H5VLintrospect_opt_query
6673
 *
6674
 * Purpose:     Calls the connector-specific callback to query if an optional
6675
 *              operation is supported.
6676
 *
6677
 * Return:      Success:    Non-negative
6678
 *              Failure:    Negative
6679
 *
6680
 *-------------------------------------------------------------------------
6681
 */
6682
herr_t
6683
H5VLintrospect_opt_query(void *obj, hid_t connector_id, H5VL_subclass_t subcls, int opt_type,
6684
                         uint64_t *flags /*out*/)
6685
0
{
6686
0
    H5VL_connector_t *connector;           /* VOL connector */
6687
0
    herr_t            ret_value = SUCCEED; /* Return value */
6688
6689
0
    FUNC_ENTER_API_NOINIT
6690
6691
    /* Get connector pointer */
6692
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6693
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6694
6695
    /* Call the corresponding internal VOL routine */
6696
0
    if (H5VL__introspect_opt_query(obj, connector->cls, subcls, opt_type, flags) < 0)
6697
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query optional operation support");
6698
6699
0
done:
6700
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6701
0
} /* end H5VLintrospect_opt_query() */
6702
6703
/*-------------------------------------------------------------------------
6704
 * Function:    H5VL__request_wait
6705
 *
6706
 * Purpose:     Waits on an asynchronous request through the VOL
6707
 *
6708
 * Return:      Success:    Non-negative
6709
 *              Failure:    Negative
6710
 *
6711
 *-------------------------------------------------------------------------
6712
 */
6713
static herr_t
6714
H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, H5VL_request_status_t *status)
6715
0
{
6716
0
    herr_t ret_value = SUCCEED; /* Return value */
6717
6718
0
    FUNC_ENTER_PACKAGE
6719
6720
    /* Sanity checks */
6721
0
    assert(req);
6722
0
    assert(cls);
6723
0
    assert(status);
6724
6725
    /* Check if the corresponding VOL callback exists */
6726
0
    if (NULL == cls->request_cls.wait)
6727
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async wait' method");
6728
6729
    /* Prepare & restore library for user callback */
6730
0
    H5_BEFORE_USER_CB(FAIL)
6731
0
        {
6732
            /* Call the corresponding VOL callback */
6733
0
            ret_value = (cls->request_cls.wait)(req, timeout, status);
6734
0
        }
6735
0
    H5_AFTER_USER_CB(FAIL)
6736
0
    if (ret_value < 0)
6737
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request wait failed");
6738
6739
0
done:
6740
0
    FUNC_LEAVE_NOAPI(ret_value)
6741
0
} /* end H5VL__request_wait() */
6742
6743
/*-------------------------------------------------------------------------
6744
 * Function:    H5VL_request_wait
6745
 *
6746
 * Purpose:     Waits on an asynchronous request through the VOL
6747
 *
6748
 * Return:      Success:    Non-negative
6749
 *              Failure:    Negative
6750
 *
6751
 *-------------------------------------------------------------------------
6752
 */
6753
herr_t
6754
H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status)
6755
0
{
6756
0
    bool   vol_wrapper_set = false;
6757
0
    herr_t ret_value       = SUCCEED; /* Return value */
6758
6759
0
    FUNC_ENTER_NOAPI(FAIL)
6760
6761
    /* Sanity checks */
6762
0
    assert(vol_obj);
6763
6764
    /* Set wrapper info in API context */
6765
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6766
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6767
0
    vol_wrapper_set = true;
6768
6769
    /* Call the corresponding internal VOL routine */
6770
0
    if (H5VL__request_wait(vol_obj->data, vol_obj->connector->cls, timeout, status) < 0)
6771
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request wait failed");
6772
6773
0
done:
6774
    /* Reset object wrapping info in API context */
6775
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6776
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6777
6778
0
    FUNC_LEAVE_NOAPI(ret_value)
6779
0
} /* end H5VL_request_wait() */
6780
6781
/*-------------------------------------------------------------------------
6782
 * Function:    H5VLrequest_wait
6783
 *
6784
 * Purpose:     Waits on a request
6785
 *
6786
 * Return:      Success:    Non-negative
6787
 *              Failure:    Negative
6788
 *
6789
 *-------------------------------------------------------------------------
6790
 */
6791
herr_t
6792
H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5VL_request_status_t *status /*out*/)
6793
0
{
6794
0
    H5VL_connector_t *connector;           /* VOL connector */
6795
0
    herr_t            ret_value = SUCCEED; /* Return value */
6796
6797
0
    FUNC_ENTER_API_NOINIT
6798
6799
    /* Get connector pointer */
6800
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6801
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6802
6803
    /* Call the corresponding internal VOL routine */
6804
0
    if (H5VL__request_wait(req, connector->cls, timeout, status) < 0)
6805
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to wait on request");
6806
6807
0
done:
6808
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6809
0
} /* end H5VLrequest_wait() */
6810
6811
/*-------------------------------------------------------------------------
6812
 * Function:    H5VL__request_notify
6813
 *
6814
 * Purpose:     Registers a user callback to be invoked when an asynchronous
6815
 *    operation completes
6816
 *
6817
 * Return:      Success:    Non-negative
6818
 *              Failure:    Negative
6819
 *
6820
 *-------------------------------------------------------------------------
6821
 */
6822
static herr_t
6823
H5VL__request_notify(void *req, const H5VL_class_t *cls, H5VL_request_notify_t cb, void *ctx)
6824
0
{
6825
0
    herr_t ret_value = SUCCEED; /* Return value */
6826
6827
0
    FUNC_ENTER_PACKAGE
6828
6829
    /* Sanity check */
6830
0
    assert(req);
6831
0
    assert(cls);
6832
6833
    /* Check if the corresponding VOL callback exists */
6834
0
    if (NULL == cls->request_cls.notify)
6835
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async notify' method");
6836
6837
    /* Prepare & restore library for user callback */
6838
0
    H5_BEFORE_USER_CB(FAIL)
6839
0
        {
6840
            /* Call the corresponding VOL callback */
6841
0
            ret_value = (cls->request_cls.notify)(req, cb, ctx);
6842
0
        }
6843
0
    H5_AFTER_USER_CB(FAIL)
6844
0
    if (ret_value < 0)
6845
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request notify failed");
6846
6847
0
done:
6848
0
    FUNC_LEAVE_NOAPI(ret_value)
6849
0
} /* end H5VL__request_notify() */
6850
6851
/*-------------------------------------------------------------------------
6852
 * Function:    H5VL_request_notify
6853
 *
6854
 * Purpose:     Registers a user callback to be invoked when an asynchronous
6855
 *    operation completes
6856
 *
6857
 * Return:      Success:    Non-negative
6858
 *              Failure:    Negative
6859
 *
6860
 *-------------------------------------------------------------------------
6861
 */
6862
herr_t
6863
H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx)
6864
0
{
6865
0
    bool   vol_wrapper_set = false;
6866
0
    herr_t ret_value       = SUCCEED; /* Return value */
6867
6868
0
    FUNC_ENTER_NOAPI(FAIL)
6869
6870
    /* Sanity check */
6871
0
    assert(vol_obj);
6872
6873
    /* Set wrapper info in API context */
6874
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6875
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6876
0
    vol_wrapper_set = true;
6877
6878
    /* Call the corresponding internal VOL routine */
6879
0
    if (H5VL__request_notify(vol_obj->data, vol_obj->connector->cls, cb, ctx) < 0)
6880
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "request notify failed");
6881
6882
0
done:
6883
    /* Reset object wrapping info in API context */
6884
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6885
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6886
6887
0
    FUNC_LEAVE_NOAPI(ret_value)
6888
0
} /* end H5VL_request_notify() */
6889
6890
/*-------------------------------------------------------------------------
6891
 * Function:    H5VLrequest_notify
6892
 *
6893
 * Purpose:     Registers a user callback to be invoked when an asynchronous
6894
 *    operation completes
6895
 *
6896
 * Return:      Success:    Non-negative
6897
 *              Failure:    Negative
6898
 *
6899
 *-------------------------------------------------------------------------
6900
 */
6901
herr_t
6902
H5VLrequest_notify(void *req, hid_t connector_id, H5VL_request_notify_t cb, void *ctx)
6903
0
{
6904
0
    H5VL_connector_t *connector;           /* VOL connector */
6905
0
    herr_t            ret_value = SUCCEED; /* Return value */
6906
6907
0
    FUNC_ENTER_API_NOINIT
6908
6909
    /* Get connector pointer */
6910
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
6911
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
6912
6913
    /* Call the corresponding internal VOL routine */
6914
0
    if (H5VL__request_notify(req, connector->cls, cb, ctx) < 0)
6915
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "unable to register notify callback for request");
6916
6917
0
done:
6918
0
    FUNC_LEAVE_API_NOINIT(ret_value)
6919
0
} /* end H5VLrequest_notify() */
6920
6921
/*-------------------------------------------------------------------------
6922
 * Function:    H5VL__request_cancel
6923
 *
6924
 * Purpose:     Cancels an asynchronous request through the VOL
6925
 *
6926
 * Return:      Success:    Non-negative
6927
 *              Failure:    Negative
6928
 *
6929
 *-------------------------------------------------------------------------
6930
 */
6931
static herr_t
6932
H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status)
6933
0
{
6934
0
    herr_t ret_value = SUCCEED; /* Return value */
6935
6936
0
    FUNC_ENTER_PACKAGE
6937
6938
    /* Sanity check */
6939
0
    assert(req);
6940
0
    assert(cls);
6941
6942
    /* Check if the corresponding VOL callback exists */
6943
0
    if (NULL == cls->request_cls.cancel)
6944
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async cancel' method");
6945
6946
    /* Prepare & restore library for user callback */
6947
0
    H5_BEFORE_USER_CB(FAIL)
6948
0
        {
6949
            /* Call the corresponding VOL callback */
6950
0
            ret_value = (cls->request_cls.cancel)(req, status);
6951
0
        }
6952
0
    H5_AFTER_USER_CB(FAIL)
6953
0
    if (ret_value < 0)
6954
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed");
6955
6956
0
done:
6957
0
    FUNC_LEAVE_NOAPI(ret_value)
6958
0
} /* end H5VL__request_cancel() */
6959
6960
/*-------------------------------------------------------------------------
6961
 * Function:    H5VL_request_cancel
6962
 *
6963
 * Purpose:     Cancels an asynchronous request through the VOL
6964
 *
6965
 * Return:      Success:    Non-negative
6966
 *              Failure:    Negative
6967
 *
6968
 *-------------------------------------------------------------------------
6969
 */
6970
herr_t
6971
H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status)
6972
0
{
6973
0
    bool   vol_wrapper_set = false;
6974
0
    herr_t ret_value       = SUCCEED; /* Return value */
6975
6976
0
    FUNC_ENTER_NOAPI(FAIL)
6977
6978
    /* Sanity check */
6979
0
    assert(vol_obj);
6980
6981
    /* Set wrapper info in API context */
6982
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
6983
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
6984
0
    vol_wrapper_set = true;
6985
6986
    /* Call the corresponding internal VOL routine */
6987
0
    if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls, status) < 0)
6988
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed");
6989
6990
0
done:
6991
    /* Reset object wrapping info in API context */
6992
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
6993
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
6994
6995
0
    FUNC_LEAVE_NOAPI(ret_value)
6996
0
} /* end H5VL_request_cancel() */
6997
6998
/*-------------------------------------------------------------------------
6999
 * Function:    H5VLrequest_cancel
7000
 *
7001
 * Purpose:     Cancels a request
7002
 *
7003
 * Return:      Success:    Non-negative
7004
 *              Failure:    Negative
7005
 *
7006
 *-------------------------------------------------------------------------
7007
 */
7008
herr_t
7009
H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status /*out*/)
7010
0
{
7011
0
    H5VL_connector_t *connector;           /* VOL connector */
7012
0
    herr_t            ret_value = SUCCEED; /* Return value */
7013
7014
0
    FUNC_ENTER_API_NOINIT
7015
7016
    /* Get connector pointer */
7017
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7018
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7019
7020
    /* Call the corresponding internal VOL routine */
7021
0
    if (H5VL__request_cancel(req, connector->cls, status) < 0)
7022
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to cancel request");
7023
7024
0
done:
7025
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7026
0
} /* end H5VLrequest_cancel() */
7027
7028
/*-------------------------------------------------------------------------
7029
 * Function:    H5VL__request_specific
7030
 *
7031
 * Purpose: Specific operation on asynchronous request through the VOL
7032
 *
7033
 * Return:      Success:    Non-negative
7034
 *              Failure:    Negative
7035
 *
7036
 *-------------------------------------------------------------------------
7037
 */
7038
static herr_t
7039
H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_args_t *args)
7040
0
{
7041
0
    herr_t ret_value = SUCCEED; /* Return value */
7042
7043
0
    FUNC_ENTER_PACKAGE
7044
7045
    /* Sanity check */
7046
0
    assert(req);
7047
0
    assert(cls);
7048
7049
    /* Check if the corresponding VOL callback exists */
7050
0
    if (NULL == cls->request_cls.specific)
7051
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async specific' method");
7052
7053
    /* Prepare & restore library for user callback */
7054
0
    H5_BEFORE_USER_CB(FAIL)
7055
0
        {
7056
            /* Call the corresponding VOL callback */
7057
0
            ret_value = (cls->request_cls.specific)(req, args);
7058
0
        }
7059
0
    H5_AFTER_USER_CB(FAIL)
7060
0
    if (ret_value < 0)
7061
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
7062
0
                    "unable to execute asynchronous request specific callback");
7063
7064
0
done:
7065
0
    FUNC_LEAVE_NOAPI(ret_value)
7066
0
} /* end H5VL__request_specific() */
7067
7068
/*-------------------------------------------------------------------------
7069
 * Function:    H5VL_request_specific
7070
 *
7071
 * Purpose: Specific operation on asynchronous request through the VOL
7072
 *
7073
 * Return:      Success:    Non-negative
7074
 *              Failure:    Negative
7075
 *
7076
 *-------------------------------------------------------------------------
7077
 */
7078
herr_t
7079
H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_args_t *args)
7080
0
{
7081
0
    bool   vol_wrapper_set = false;
7082
0
    herr_t ret_value       = SUCCEED; /* Return value */
7083
7084
0
    FUNC_ENTER_NOAPI(FAIL)
7085
7086
    /* Sanity check */
7087
0
    assert(vol_obj);
7088
7089
    /* Set wrapper info in API context */
7090
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
7091
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
7092
0
    vol_wrapper_set = true;
7093
7094
    /* Call the corresponding internal VOL routine */
7095
0
    if (H5VL__request_specific(vol_obj->data, vol_obj->connector->cls, args) < 0)
7096
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
7097
0
                    "unable to execute asynchronous request specific callback");
7098
7099
0
done:
7100
    /* Reset object wrapping info in API context */
7101
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
7102
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
7103
7104
0
    FUNC_LEAVE_NOAPI(ret_value)
7105
0
} /* end H5VL_request_specific() */
7106
7107
/*-------------------------------------------------------------------------
7108
 * Function:    H5VLrequest_specific
7109
 *
7110
 * Purpose:     Performs a connector-specific operation on an asynchronous request
7111
 *
7112
 * Return:      Success:    Non-negative
7113
 *              Failure:    Negative
7114
 *
7115
 *-------------------------------------------------------------------------
7116
 */
7117
herr_t
7118
H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_args_t *args)
7119
0
{
7120
0
    H5VL_connector_t *connector;           /* VOL connector */
7121
0
    herr_t            ret_value = SUCCEED; /* Return value */
7122
7123
0
    FUNC_ENTER_API_NOINIT
7124
7125
    /* Get connector pointer */
7126
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7127
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7128
7129
    /* Call the corresponding internal VOL routine */
7130
0
    if (H5VL__request_specific(req, connector->cls, args) < 0)
7131
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
7132
0
                    "unable to execute asynchronous request specific callback");
7133
7134
0
done:
7135
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7136
0
} /* end H5VLrequest_specific() */
7137
7138
/*-------------------------------------------------------------------------
7139
 * Function:    H5VL__request_optional
7140
 *
7141
 * Purpose: Optional operation specific to connectors.
7142
 *
7143
 * Return:      Success:    Non-negative
7144
 *              Failure:    Negative
7145
 *
7146
 *-------------------------------------------------------------------------
7147
 */
7148
static herr_t
7149
H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_optional_args_t *args)
7150
0
{
7151
0
    herr_t ret_value = SUCCEED; /* Return value */
7152
7153
0
    FUNC_ENTER_PACKAGE
7154
7155
    /* Sanity check */
7156
0
    assert(req);
7157
0
    assert(cls);
7158
7159
    /* Check if the corresponding VOL callback exists */
7160
0
    if (NULL == cls->request_cls.optional)
7161
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async optional' method");
7162
7163
    /* Prepare & restore library for user callback */
7164
0
    H5_BEFORE_USER_CB(FAIL)
7165
0
        {
7166
            /* Call the corresponding VOL callback */
7167
0
            ret_value = (cls->request_cls.optional)(req, args);
7168
0
        }
7169
0
    H5_AFTER_USER_CB(FAIL)
7170
0
    if (ret_value < 0)
7171
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
7172
0
                    "unable to execute asynchronous request optional callback");
7173
7174
0
done:
7175
0
    FUNC_LEAVE_NOAPI(ret_value)
7176
0
} /* end H5VL__request_optional() */
7177
7178
/*-------------------------------------------------------------------------
7179
 * Function:    H5VL_request_optional
7180
 *
7181
 * Purpose: Optional operation specific to connectors.
7182
 *
7183
 * Return:      Success:    Non-negative
7184
 *              Failure:    Negative
7185
 *
7186
 *-------------------------------------------------------------------------
7187
 */
7188
herr_t
7189
H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args)
7190
0
{
7191
0
    bool   vol_wrapper_set = false;
7192
0
    herr_t ret_value       = SUCCEED; /* Return value */
7193
7194
0
    FUNC_ENTER_NOAPI(FAIL)
7195
7196
    /* Sanity check */
7197
0
    assert(vol_obj);
7198
7199
    /* Set wrapper info in API context */
7200
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
7201
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
7202
0
    vol_wrapper_set = true;
7203
7204
    /* Call the corresponding internal VOL routine */
7205
0
    if (H5VL__request_optional(vol_obj->data, vol_obj->connector->cls, args) < 0)
7206
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
7207
0
                    "unable to execute asynchronous request optional callback");
7208
7209
0
done:
7210
    /* Reset object wrapping info in API context */
7211
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
7212
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
7213
7214
0
    FUNC_LEAVE_NOAPI(ret_value)
7215
0
} /* end H5VL_request_optional() */
7216
7217
/*-------------------------------------------------------------------------
7218
 * Function:    H5VLrequest_optional
7219
 *
7220
 * Purpose:     Performs an optional connector-specific operation on an asynchronous request
7221
 *
7222
 * Return:      Success:    Non-negative
7223
 *              Failure:    Negative
7224
 *
7225
 *-------------------------------------------------------------------------
7226
 */
7227
herr_t
7228
H5VLrequest_optional(void *req, hid_t connector_id, H5VL_optional_args_t *args)
7229
0
{
7230
0
    H5VL_connector_t *connector;           /* VOL connector */
7231
0
    herr_t            ret_value = SUCCEED; /* Return value */
7232
7233
0
    FUNC_ENTER_API_NOINIT
7234
7235
    /* Get connector pointer */
7236
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7237
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7238
7239
    /* Call the corresponding internal VOL routine */
7240
0
    if (H5VL__request_optional(req, connector->cls, args) < 0)
7241
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL,
7242
0
                    "unable to execute asynchronous request optional callback");
7243
7244
0
done:
7245
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7246
0
} /* end H5VLrequest_optional() */
7247
7248
/*-------------------------------------------------------------------------
7249
 * Function:    H5VLrequest_optional_op
7250
 *
7251
 * Purpose:     Performs an optional connector-specific operation on a request
7252
 *
7253
 * Return:      Success:    Non-negative
7254
 *              Failure:    Negative
7255
 *
7256
 *-------------------------------------------------------------------------
7257
 */
7258
herr_t
7259
H5VLrequest_optional_op(void *req, hid_t connector_id, H5VL_optional_args_t *args)
7260
0
{
7261
0
    H5VL_connector_t *connector;           /* VOL connector */
7262
0
    herr_t            ret_value = SUCCEED; /* Return value */
7263
7264
0
    FUNC_ENTER_API(FAIL)
7265
7266
    /* Check arguments */
7267
0
    if (NULL == req)
7268
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request");
7269
0
    if (NULL == args)
7270
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid arguments");
7271
7272
    /* Get connector pointer */
7273
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7274
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7275
7276
    /* Call the corresponding internal VOL routine */
7277
0
    if (H5VL__request_optional(req, connector->cls, args) < 0)
7278
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute request optional callback");
7279
7280
0
done:
7281
0
    FUNC_LEAVE_API(ret_value)
7282
0
} /* end H5VLrequest_optional_op() */
7283
7284
/*-------------------------------------------------------------------------
7285
 * Function:    H5VL__request_free
7286
 *
7287
 * Purpose:     Frees an asynchronous request through the VOL
7288
 *
7289
 * Return:      Success:    Non-negative
7290
 *              Failure:    Negative
7291
 *
7292
 *-------------------------------------------------------------------------
7293
 */
7294
static herr_t
7295
H5VL__request_free(void *req, const H5VL_class_t *cls)
7296
0
{
7297
0
    herr_t ret_value = SUCCEED; /* Return value */
7298
7299
0
    FUNC_ENTER_PACKAGE
7300
7301
    /* Sanity check */
7302
0
    assert(req);
7303
0
    assert(cls);
7304
7305
    /* Check if the corresponding VOL callback exists */
7306
0
    if (NULL == cls->request_cls.free)
7307
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async free' method");
7308
7309
    /* Prepare & restore library for user callback */
7310
0
    H5_BEFORE_USER_CB(FAIL)
7311
0
        {
7312
            /* Call the corresponding VOL callback */
7313
0
            ret_value = (cls->request_cls.free)(req);
7314
0
        }
7315
0
    H5_AFTER_USER_CB(FAIL)
7316
0
    if (ret_value < 0)
7317
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request free failed");
7318
7319
0
done:
7320
0
    FUNC_LEAVE_NOAPI(ret_value)
7321
0
} /* end H5VL__request_free() */
7322
7323
/*-------------------------------------------------------------------------
7324
 * Function:    H5VL_request_free
7325
 *
7326
 * Purpose:     Frees an asynchronous request through the VOL
7327
 *
7328
 * Return:      Success:    Non-negative
7329
 *              Failure:    Negative
7330
 *
7331
 *-------------------------------------------------------------------------
7332
 */
7333
herr_t
7334
H5VL_request_free(const H5VL_object_t *vol_obj)
7335
0
{
7336
0
    bool   vol_wrapper_set = false;
7337
0
    herr_t ret_value       = SUCCEED; /* Return value */
7338
7339
0
    FUNC_ENTER_NOAPI(FAIL)
7340
7341
    /* Sanity check */
7342
0
    assert(vol_obj);
7343
7344
    /* Set wrapper info in API context */
7345
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
7346
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
7347
0
    vol_wrapper_set = true;
7348
7349
    /* Call the corresponding VOL callback */
7350
0
    if (H5VL__request_free(vol_obj->data, vol_obj->connector->cls) < 0)
7351
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request free failed");
7352
7353
0
done:
7354
    /* Reset object wrapping info in API context */
7355
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
7356
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
7357
7358
0
    FUNC_LEAVE_NOAPI(ret_value)
7359
0
} /* end H5VL_request_free() */
7360
7361
/*-------------------------------------------------------------------------
7362
 * Function:    H5VLrequest_free
7363
 *
7364
 * Purpose:     Frees a request
7365
 *
7366
 * Return:      Success:    Non-negative
7367
 *              Failure:    Negative
7368
 *
7369
 *-------------------------------------------------------------------------
7370
 */
7371
herr_t
7372
H5VLrequest_free(void *req, hid_t connector_id)
7373
0
{
7374
0
    H5VL_connector_t *connector;           /* VOL connector */
7375
0
    herr_t            ret_value = SUCCEED; /* Return value */
7376
7377
0
    FUNC_ENTER_API_NOINIT
7378
7379
    /* Get connector pointer */
7380
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7381
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7382
7383
    /* Call the corresponding internal VOL routine */
7384
0
    if (H5VL__request_free(req, connector->cls) < 0)
7385
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to free request");
7386
7387
0
done:
7388
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7389
0
} /* end H5VLrequest_free() */
7390
7391
/*-------------------------------------------------------------------------
7392
 * Function:    H5VL__blob_put
7393
 *
7394
 * Purpose:     Put a blob through the VOL
7395
 *
7396
 * Return:      SUCCEED / FAIL
7397
 *
7398
 *-------------------------------------------------------------------------
7399
 */
7400
static herr_t
7401
H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size, void *blob_id, void *ctx)
7402
0
{
7403
0
    herr_t ret_value = SUCCEED; /* Return value */
7404
7405
0
    FUNC_ENTER_PACKAGE
7406
7407
    /* Sanity check */
7408
0
    assert(obj);
7409
0
    assert(cls);
7410
0
    assert(size == 0 || buf);
7411
0
    assert(blob_id);
7412
7413
    /* Check if the corresponding VOL callback exists */
7414
0
    if (NULL == cls->blob_cls.put)
7415
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob put' method");
7416
7417
    /* Prepare & restore library for user callback */
7418
0
    H5_BEFORE_USER_CB(FAIL)
7419
0
        {
7420
            /* Call the corresponding VOL callback */
7421
0
            ret_value = (cls->blob_cls.put)(obj, buf, size, blob_id, ctx);
7422
0
        }
7423
0
    H5_AFTER_USER_CB(FAIL)
7424
0
    if (ret_value < 0)
7425
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put callback failed");
7426
7427
0
done:
7428
0
    FUNC_LEAVE_NOAPI(ret_value)
7429
0
} /* end H5VL__blob_put() */
7430
7431
/*-------------------------------------------------------------------------
7432
 * Function:    H5VL_blob_put
7433
 *
7434
 * Purpose:     Put a blob through the VOL
7435
 *
7436
 * Return:      SUCCEED / FAIL
7437
 *
7438
 *-------------------------------------------------------------------------
7439
 */
7440
herr_t
7441
H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void *blob_id, void *ctx)
7442
0
{
7443
0
    herr_t ret_value = SUCCEED; /* Return value */
7444
7445
0
    FUNC_ENTER_NOAPI(FAIL)
7446
7447
    /* Sanity check */
7448
0
    assert(vol_obj);
7449
0
    assert(size == 0 || buf);
7450
0
    assert(blob_id);
7451
7452
    /* Call the corresponding VOL callback */
7453
0
    if (H5VL__blob_put(vol_obj->data, vol_obj->connector->cls, buf, size, blob_id, ctx) < 0)
7454
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed");
7455
7456
0
done:
7457
0
    FUNC_LEAVE_NOAPI(ret_value)
7458
0
} /* end H5VL_blob_put() */
7459
7460
/*-------------------------------------------------------------------------
7461
 * Function:    H5VLblob_put
7462
 *
7463
 * Purpose:     Put a blob through the VOL
7464
 *
7465
 * Return:      SUCCEED / FAIL
7466
 *
7467
 *-------------------------------------------------------------------------
7468
 */
7469
herr_t
7470
H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, void *blob_id, void *ctx)
7471
0
{
7472
0
    H5VL_connector_t *connector;           /* VOL connector */
7473
0
    herr_t            ret_value = SUCCEED; /* Return value */
7474
7475
0
    FUNC_ENTER_API_NOINIT
7476
7477
    /* Get connector pointer */
7478
0
    if (NULL == obj)
7479
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
7480
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7481
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7482
7483
    /* Call the corresponding VOL callback */
7484
0
    if (H5VL__blob_put(obj, connector->cls, buf, size, blob_id, ctx) < 0)
7485
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed");
7486
7487
0
done:
7488
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7489
0
} /* end H5VLblob_put() */
7490
7491
/*-------------------------------------------------------------------------
7492
 * Function:    H5VL__blob_get
7493
 *
7494
 * Purpose:     Get a blob through the VOL
7495
 *
7496
 * Return:      SUCCEED / FAIL
7497
 *
7498
 *-------------------------------------------------------------------------
7499
 */
7500
static herr_t
7501
H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id, void *buf, size_t size, void *ctx)
7502
0
{
7503
0
    herr_t ret_value = SUCCEED; /* Return value */
7504
7505
0
    FUNC_ENTER_PACKAGE
7506
7507
    /* Sanity check */
7508
0
    assert(obj);
7509
0
    assert(cls);
7510
0
    assert(blob_id);
7511
0
    assert(buf);
7512
7513
    /* Check if the corresponding VOL callback exists */
7514
0
    if (NULL == cls->blob_cls.get)
7515
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob get' method");
7516
7517
    /* Prepare & restore library for user callback */
7518
0
    H5_BEFORE_USER_CB(FAIL)
7519
0
        {
7520
            /* Call the corresponding VOL callback */
7521
0
            ret_value = (cls->blob_cls.get)(obj, blob_id, buf, size, ctx);
7522
0
        }
7523
0
    H5_AFTER_USER_CB(FAIL)
7524
0
    if (ret_value < 0)
7525
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get callback failed");
7526
7527
0
done:
7528
0
    FUNC_LEAVE_NOAPI(ret_value)
7529
0
} /* end H5VL__blob_get() */
7530
7531
/*-------------------------------------------------------------------------
7532
 * Function:    H5VL_blob_get
7533
 *
7534
 * Purpose:     Get a blob through the VOL
7535
 *
7536
 * Return:      SUCCEED / FAIL
7537
 *
7538
 *-------------------------------------------------------------------------
7539
 */
7540
herr_t
7541
H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t size, void *ctx)
7542
0
{
7543
0
    herr_t ret_value = SUCCEED; /* Return value */
7544
7545
0
    FUNC_ENTER_NOAPI(FAIL)
7546
7547
    /* Sanity check */
7548
0
    assert(vol_obj);
7549
0
    assert(blob_id);
7550
0
    assert(buf);
7551
7552
    /* Call the corresponding VOL callback */
7553
0
    if (H5VL__blob_get(vol_obj->data, vol_obj->connector->cls, blob_id, buf, size, ctx) < 0)
7554
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed");
7555
7556
0
done:
7557
0
    FUNC_LEAVE_NOAPI(ret_value)
7558
0
} /* end H5VL_blob_get() */
7559
7560
/*-------------------------------------------------------------------------
7561
 * Function:    H5VLblob_get
7562
 *
7563
 * Purpose:     Get a blob through the VOL
7564
 *
7565
 * Return:      SUCCEED / FAIL
7566
 *
7567
 *-------------------------------------------------------------------------
7568
 */
7569
herr_t
7570
H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf /*out*/, size_t size, void *ctx)
7571
0
{
7572
0
    H5VL_connector_t *connector;           /* VOL connector */
7573
0
    herr_t            ret_value = SUCCEED; /* Return value */
7574
7575
0
    FUNC_ENTER_API_NOINIT
7576
7577
    /* Get connector pointer */
7578
0
    if (NULL == obj)
7579
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
7580
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7581
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7582
7583
    /* Call the corresponding VOL callback */
7584
0
    if (H5VL__blob_get(obj, connector->cls, blob_id, buf, size, ctx) < 0)
7585
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed");
7586
7587
0
done:
7588
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7589
0
} /* end H5VLblob_get() */
7590
7591
/*-------------------------------------------------------------------------
7592
 * Function:    H5VL__blob_specific
7593
 *
7594
 * Purpose: Specific operation on blobs through the VOL
7595
 *
7596
 * Return:      SUCCEED / FAIL
7597
 *
7598
 *-------------------------------------------------------------------------
7599
 */
7600
static herr_t
7601
H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_specific_args_t *args)
7602
0
{
7603
0
    herr_t ret_value = SUCCEED; /* Return value */
7604
7605
0
    FUNC_ENTER_PACKAGE
7606
7607
    /* Sanity check */
7608
0
    assert(obj);
7609
0
    assert(cls);
7610
0
    assert(blob_id);
7611
7612
    /* Check if the corresponding VOL callback exists */
7613
0
    if (NULL == cls->blob_cls.specific)
7614
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method");
7615
7616
    /* Prepare & restore library for user callback */
7617
0
    H5_BEFORE_USER_CB(FAIL)
7618
0
        {
7619
            /* Call the corresponding VOL callback */
7620
0
            ret_value = (cls->blob_cls.specific)(obj, blob_id, args);
7621
0
        }
7622
0
    H5_AFTER_USER_CB(FAIL)
7623
0
    if (ret_value < 0)
7624
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback");
7625
7626
0
done:
7627
0
    FUNC_LEAVE_NOAPI(ret_value)
7628
0
} /* end H5VL__blob_specific() */
7629
7630
/*-------------------------------------------------------------------------
7631
 * Function:    H5VL_blob_specific
7632
 *
7633
 * Purpose: Specific operation on blobs through the VOL
7634
 *
7635
 * Return:      Success:    Non-negative
7636
 *              Failure:    Negative
7637
 *
7638
 *-------------------------------------------------------------------------
7639
 */
7640
herr_t
7641
H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_args_t *args)
7642
0
{
7643
0
    herr_t ret_value = SUCCEED; /* Return value */
7644
7645
0
    FUNC_ENTER_NOAPI(FAIL)
7646
7647
    /* Sanity check */
7648
0
    assert(vol_obj);
7649
0
    assert(blob_id);
7650
7651
    /* Call the corresponding internal VOL routine */
7652
0
    if (H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, args) < 0)
7653
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback");
7654
7655
0
done:
7656
0
    FUNC_LEAVE_NOAPI(ret_value)
7657
0
} /* end H5VL_blob_specific() */
7658
7659
/*-------------------------------------------------------------------------
7660
 * Function:    H5VLblob_specific
7661
 *
7662
 * Purpose: Specific operation on blobs through the VOL
7663
 *
7664
 * Return:      SUCCEED / FAIL
7665
 *
7666
 *-------------------------------------------------------------------------
7667
 */
7668
herr_t
7669
H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_args_t *args)
7670
0
{
7671
0
    H5VL_connector_t *connector;           /* VOL connector */
7672
0
    herr_t            ret_value = SUCCEED; /* Return value */
7673
7674
0
    FUNC_ENTER_API_NOINIT
7675
7676
    /* Get connector pointer */
7677
0
    if (NULL == obj)
7678
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
7679
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7680
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7681
7682
    /* Call the corresponding VOL callback */
7683
0
    if (H5VL__blob_specific(obj, connector->cls, blob_id, args) < 0)
7684
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob specific operation failed");
7685
7686
0
done:
7687
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7688
0
} /* end H5VLblob_specific() */
7689
7690
/*-------------------------------------------------------------------------
7691
 * Function:    H5VL__blob_optional
7692
 *
7693
 * Purpose: Optional operation on blobs through the VOL
7694
 *
7695
 * Return:      SUCCEED / FAIL
7696
 *
7697
 *-------------------------------------------------------------------------
7698
 */
7699
static herr_t
7700
H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_optional_args_t *args)
7701
0
{
7702
0
    herr_t ret_value = SUCCEED; /* Return value */
7703
7704
0
    FUNC_ENTER_PACKAGE
7705
7706
    /* Sanity check */
7707
0
    assert(obj);
7708
0
    assert(cls);
7709
0
    assert(blob_id);
7710
7711
    /* Check if the corresponding VOL callback exists */
7712
0
    if (NULL == cls->blob_cls.optional)
7713
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob optional' method");
7714
7715
    /* Prepare & restore library for user callback */
7716
0
    H5_BEFORE_USER_CB(FAIL)
7717
0
        {
7718
            /* Call the corresponding VOL callback */
7719
0
            ret_value = (cls->blob_cls.optional)(obj, blob_id, args);
7720
0
        }
7721
0
    H5_AFTER_USER_CB(FAIL)
7722
0
    if (ret_value < 0)
7723
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob optional callback");
7724
7725
0
done:
7726
0
    FUNC_LEAVE_NOAPI(ret_value)
7727
0
} /* end H5VL__blob_optional() */
7728
7729
/*-------------------------------------------------------------------------
7730
 * Function:    H5VL_blob_optional
7731
 *
7732
 * Purpose: Optional operation on blobs through the VOL
7733
 *
7734
 * Return:      Success:    Non-negative
7735
 *              Failure:    Negative
7736
 *
7737
 *-------------------------------------------------------------------------
7738
 */
7739
herr_t
7740
H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_optional_args_t *args)
7741
0
{
7742
0
    herr_t ret_value = SUCCEED; /* Return value */
7743
7744
0
    FUNC_ENTER_NOAPI(FAIL)
7745
7746
    /* Sanity check */
7747
0
    assert(vol_obj);
7748
0
    assert(blob_id);
7749
7750
    /* Call the corresponding internal VOL routine */
7751
0
    if (H5VL__blob_optional(vol_obj->data, vol_obj->connector->cls, blob_id, args) < 0)
7752
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob optional callback");
7753
7754
0
done:
7755
0
    FUNC_LEAVE_NOAPI(ret_value)
7756
0
} /* end H5VL_blob_optional() */
7757
7758
/*-------------------------------------------------------------------------
7759
 * Function:    H5VLblob_optional
7760
 *
7761
 * Purpose: Optional operation on blobs through the VOL
7762
 *
7763
 * Return:      SUCCEED / FAIL
7764
 *
7765
 *-------------------------------------------------------------------------
7766
 */
7767
herr_t
7768
H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_optional_args_t *args)
7769
0
{
7770
0
    H5VL_connector_t *connector;           /* VOL connector */
7771
0
    herr_t            ret_value = SUCCEED; /* Return value */
7772
7773
0
    FUNC_ENTER_API_NOINIT
7774
7775
    /* Get connector pointer */
7776
0
    if (NULL == obj)
7777
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
7778
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7779
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7780
7781
    /* Call the corresponding VOL callback */
7782
0
    if (H5VL__blob_optional(obj, connector->cls, blob_id, args) < 0)
7783
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob optional operation failed");
7784
7785
0
done:
7786
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7787
0
} /* end H5VLblob_optional() */
7788
7789
/*-------------------------------------------------------------------------
7790
 * Function:    H5VL__token_cmp
7791
 *
7792
 * Purpose:     Compares two VOL connector object tokens. Sets *cmp_value
7793
 *              to positive if token1 is greater than token2, negative if
7794
 *              token2 is greater than token1 and zero if token1 and
7795
 *              token2 are equal.
7796
 *
7797
 * Return:      Success:    Non-negative
7798
 *              Failure:    Negative
7799
 *
7800
 *-------------------------------------------------------------------------
7801
 */
7802
static herr_t
7803
H5VL__token_cmp(void *obj, const H5VL_class_t *cls, const H5O_token_t *token1, const H5O_token_t *token2,
7804
                int *cmp_value)
7805
0
{
7806
0
    herr_t ret_value = SUCCEED; /* Return value */
7807
7808
0
    FUNC_ENTER_PACKAGE
7809
7810
    /* Sanity checks */
7811
0
    assert(obj);
7812
0
    assert(cls);
7813
0
    assert(cmp_value);
7814
7815
    /* Take care of cases where one or both pointers is NULL */
7816
0
    if (token1 == NULL && token2 != NULL)
7817
0
        *cmp_value = -1;
7818
0
    else if (token1 != NULL && token2 == NULL)
7819
0
        *cmp_value = 1;
7820
0
    else if (token1 == NULL && token2 == NULL)
7821
0
        *cmp_value = 0;
7822
0
    else {
7823
        /* Use the class's token comparison routine to compare the tokens,
7824
         * if there is a callback, otherwise just compare the tokens as
7825
         * memory buffers.
7826
         */
7827
0
        if (cls->token_cls.cmp) {
7828
            /* Prepare & restore library for user callback */
7829
0
            H5_BEFORE_USER_CB(FAIL)
7830
0
                {
7831
0
                    ret_value = (cls->token_cls.cmp)(obj, token1, token2, cmp_value);
7832
0
                }
7833
0
            H5_AFTER_USER_CB(FAIL)
7834
0
            if (ret_value < 0)
7835
0
                HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare object tokens");
7836
0
        } /* end if */
7837
0
        else
7838
0
            *cmp_value = memcmp(token1, token2, sizeof(H5O_token_t));
7839
0
    } /* end else */
7840
7841
0
done:
7842
0
    FUNC_LEAVE_NOAPI(ret_value)
7843
0
} /* end H5VL__token_cmp() */
7844
7845
/*-------------------------------------------------------------------------
7846
 * Function:    H5VL_token_cmp
7847
 *
7848
 * Purpose:     Compares two VOL connector object tokens. Sets *cmp_value
7849
 *              to positive if token1 is greater than token2, negative if
7850
 *              token2 is greater than token1 and zero if token1 and
7851
 *              token2 are equal.
7852
 *
7853
 * Return:      Success:    Non-negative
7854
 *              Failure:    Negative
7855
 *
7856
 *-------------------------------------------------------------------------
7857
 */
7858
herr_t
7859
H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, const H5O_token_t *token2,
7860
               int *cmp_value)
7861
0
{
7862
0
    herr_t ret_value = SUCCEED; /* Return value */
7863
7864
0
    FUNC_ENTER_NOAPI(FAIL)
7865
7866
    /* Sanity checks */
7867
0
    assert(vol_obj);
7868
0
    assert(cmp_value);
7869
7870
    /* Call the corresponding internal VOL routine */
7871
0
    if (H5VL__token_cmp(vol_obj->data, vol_obj->connector->cls, token1, token2, cmp_value) < 0)
7872
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "token compare failed");
7873
7874
0
done:
7875
0
    FUNC_LEAVE_NOAPI(ret_value)
7876
0
} /* end H5VL_token_cmp() */
7877
7878
/*---------------------------------------------------------------------------
7879
 * Function:    H5VLtoken_cmp
7880
 *
7881
 * Purpose:     Compares two VOL connector object tokens
7882
 *
7883
 * Note:        Both object tokens must be from the same VOL connector class
7884
 *
7885
 * Return:      Success:    Non-negative, with *cmp_value set to positive if
7886
 *                          token1 is greater than token2, negative if token2
7887
 *                          is greater than token1 and zero if token1 and
7888
 *                          token2 are equal.
7889
 *              Failure:    Negative
7890
 *
7891
 *---------------------------------------------------------------------------
7892
 */
7893
herr_t
7894
H5VLtoken_cmp(void *obj, hid_t connector_id, const H5O_token_t *token1, const H5O_token_t *token2,
7895
              int *cmp_value)
7896
0
{
7897
0
    H5VL_connector_t *connector;           /* VOL connector */
7898
0
    herr_t            ret_value = SUCCEED; /* Return value */
7899
7900
0
    FUNC_ENTER_API_NOINIT
7901
7902
    /* Check args and get connector pointer */
7903
0
    if (NULL == obj)
7904
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
7905
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
7906
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
7907
0
    if (NULL == cmp_value)
7908
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid cmp_value pointer");
7909
7910
    /* Call the corresponding internal VOL routine */
7911
0
    if (H5VL__token_cmp(obj, connector->cls, token1, token2, cmp_value) < 0)
7912
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "object token comparison failed");
7913
7914
0
done:
7915
0
    FUNC_LEAVE_API_NOINIT(ret_value)
7916
0
} /* end H5VLtoken_cmp() */
7917
7918
/*-------------------------------------------------------------------------
7919
 * Function:    H5VL__token_to_str
7920
 *
7921
 * Purpose:     Serialize a connector's object token into a string
7922
 *
7923
 * Return:      Success:    Non-negative
7924
 *              Failure:    Negative
7925
 *
7926
 *-------------------------------------------------------------------------
7927
 */
7928
static herr_t
7929
H5VL__token_to_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, const H5O_token_t *token,
7930
                   char **token_str)
7931
0
{
7932
0
    herr_t ret_value = SUCCEED; /* Return value */
7933
7934
0
    FUNC_ENTER_PACKAGE
7935
7936
    /* Sanity checks */
7937
0
    assert(obj);
7938
0
    assert(cls);
7939
0
    assert(token);
7940
0
    assert(token_str);
7941
7942
    /* Use the class's token serialization routine on the token if there is a
7943
     *  callback, otherwise just set the token_str to NULL.
7944
     */
7945
0
    if (cls->token_cls.to_str) {
7946
        /* Prepare & restore library for user callback */
7947
0
        H5_BEFORE_USER_CB(FAIL)
7948
0
            {
7949
0
                ret_value = (cls->token_cls.to_str)(obj, obj_type, token, token_str);
7950
0
            }
7951
0
        H5_AFTER_USER_CB(FAIL)
7952
0
        if (ret_value < 0)
7953
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "can't serialize object token");
7954
0
    } /* end if */
7955
0
    else
7956
0
        *token_str = NULL;
7957
7958
0
done:
7959
0
    FUNC_LEAVE_NOAPI(ret_value)
7960
0
} /* end H5VL__token_to_str() */
7961
7962
/*-------------------------------------------------------------------------
7963
 * Function:    H5VL_token_to_str
7964
 *
7965
 * Purpose:     Serialize a connector's object token into a string
7966
 *
7967
 * Return:      Success:    Non-negative
7968
 *              Failure:    Negative
7969
 *
7970
 *-------------------------------------------------------------------------
7971
 */
7972
herr_t
7973
H5VL_token_to_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const H5O_token_t *token,
7974
                  char **token_str)
7975
0
{
7976
0
    herr_t ret_value = SUCCEED; /* Return value */
7977
7978
0
    FUNC_ENTER_NOAPI(FAIL)
7979
7980
    /* Sanity checks */
7981
0
    assert(vol_obj);
7982
0
    assert(token);
7983
0
    assert(token_str);
7984
7985
    /* Call the corresponding internal VOL routine */
7986
0
    if (H5VL__token_to_str(vol_obj->data, obj_type, vol_obj->connector->cls, token, token_str) < 0)
7987
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "token serialization failed");
7988
7989
0
done:
7990
0
    FUNC_LEAVE_NOAPI(ret_value)
7991
0
} /* end H5VL_token_to_str() */
7992
7993
/*---------------------------------------------------------------------------
7994
 * Function:    H5VLtoken_to_str
7995
 *
7996
 * Purpose:     Serialize a connector's object token into a string
7997
 *
7998
 * Return:      Success:    Non-negative
7999
 *              Failure:    Negative
8000
 *
8001
 *---------------------------------------------------------------------------
8002
 */
8003
herr_t
8004
H5VLtoken_to_str(void *obj, H5I_type_t obj_type, hid_t connector_id, const H5O_token_t *token,
8005
                 char **token_str)
8006
0
{
8007
0
    H5VL_connector_t *connector;           /* VOL connector */
8008
0
    herr_t            ret_value = SUCCEED; /* Return value */
8009
8010
0
    FUNC_ENTER_API_NOINIT
8011
8012
    /* Check args and get connector pointer */
8013
0
    if (NULL == obj)
8014
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
8015
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
8016
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
8017
0
    if (NULL == token)
8018
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token pointer");
8019
0
    if (NULL == token_str)
8020
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token_str pointer");
8021
8022
    /* Call the corresponding internal VOL routine */
8023
0
    if (H5VL__token_to_str(obj, obj_type, connector->cls, token, token_str) < 0)
8024
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "object token to string failed");
8025
8026
0
done:
8027
0
    FUNC_LEAVE_API_NOINIT(ret_value)
8028
0
} /* end H5VLtoken_to_str() */
8029
8030
/*-------------------------------------------------------------------------
8031
 * Function:    H5VL__token_from_str
8032
 *
8033
 * Purpose:     Deserialize a string into a connector object token
8034
 *
8035
 * Return:      Success:    Non-negative
8036
 *              Failure:    Negative
8037
 *
8038
 *-------------------------------------------------------------------------
8039
 */
8040
static herr_t
8041
H5VL__token_from_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, const char *token_str,
8042
                     H5O_token_t *token)
8043
0
{
8044
0
    herr_t ret_value = SUCCEED; /* Return value */
8045
8046
0
    FUNC_ENTER_PACKAGE
8047
8048
    /* Sanity checks */
8049
0
    assert(obj);
8050
0
    assert(cls);
8051
0
    assert(token_str);
8052
0
    assert(token);
8053
8054
    /* Use the class's token deserialization routine on the token if there is a
8055
     *  callback, otherwise just set the token to H5_TOKEN_UNDEF.
8056
     */
8057
0
    if (cls->token_cls.from_str) {
8058
        /* Prepare & restore library for user callback */
8059
0
        H5_BEFORE_USER_CB(FAIL)
8060
0
            {
8061
0
                ret_value = (cls->token_cls.from_str)(obj, obj_type, token_str, token);
8062
0
            }
8063
0
        H5_AFTER_USER_CB(FAIL)
8064
0
        if (ret_value < 0)
8065
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize object token string");
8066
0
    } /* end if */
8067
0
    else
8068
0
        *token = H5O_TOKEN_UNDEF;
8069
8070
0
done:
8071
0
    FUNC_LEAVE_NOAPI(ret_value)
8072
0
} /* end H5VL__token_from_str() */
8073
8074
/*-------------------------------------------------------------------------
8075
 * Function:    H5VL_token_from_str
8076
 *
8077
 * Purpose:     Deserialize a string into a connector object token
8078
 *
8079
 * Return:      Success:    Non-negative
8080
 *              Failure:    Negative
8081
 *
8082
 *-------------------------------------------------------------------------
8083
 */
8084
herr_t
8085
H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const char *token_str,
8086
                    H5O_token_t *token)
8087
0
{
8088
0
    herr_t ret_value = SUCCEED; /* Return value */
8089
8090
0
    FUNC_ENTER_NOAPI(FAIL)
8091
8092
    /* Sanity checks */
8093
0
    assert(vol_obj);
8094
0
    assert(token);
8095
0
    assert(token_str);
8096
8097
    /* Call the corresponding internal VOL routine */
8098
0
    if (H5VL__token_from_str(vol_obj->data, obj_type, vol_obj->connector->cls, token_str, token) < 0)
8099
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "token deserialization failed");
8100
8101
0
done:
8102
0
    FUNC_LEAVE_NOAPI(ret_value)
8103
0
} /* end H5VL_token_from_str() */
8104
8105
/*---------------------------------------------------------------------------
8106
 * Function:    H5VLtoken_from_str
8107
 *
8108
 * Purpose:     Deserialize a string into a connector object token
8109
 *
8110
 * Return:      Success:    Non-negative
8111
 *              Failure:    Negative
8112
 *
8113
 *---------------------------------------------------------------------------
8114
 */
8115
herr_t
8116
H5VLtoken_from_str(void *obj, H5I_type_t obj_type, hid_t connector_id, const char *token_str,
8117
                   H5O_token_t *token)
8118
0
{
8119
0
    H5VL_connector_t *connector;           /* VOL connector */
8120
0
    herr_t            ret_value = SUCCEED; /* Return value */
8121
8122
0
    FUNC_ENTER_API_NOINIT
8123
8124
    /* Check args and get connector pointer */
8125
0
    if (NULL == obj)
8126
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
8127
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
8128
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
8129
0
    if (NULL == token)
8130
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token pointer");
8131
0
    if (NULL == token_str)
8132
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid token_str pointer");
8133
8134
    /* Call the corresponding internal VOL routine */
8135
0
    if (H5VL__token_from_str(obj, obj_type, connector->cls, token_str, token) < 0)
8136
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "object token from string failed");
8137
8138
0
done:
8139
0
    FUNC_LEAVE_API_NOINIT(ret_value)
8140
0
} /* end H5VLtoken_from_str() */
8141
8142
/*-------------------------------------------------------------------------
8143
 * Function:    H5VL__optional
8144
 *
8145
 * Purpose:     Optional operation specific to connectors.
8146
 *
8147
 * Return:      Success:    Non-negative
8148
 *              Failure:    Negative
8149
 *
8150
 *-------------------------------------------------------------------------
8151
 */
8152
static herr_t
8153
H5VL__optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
8154
0
{
8155
0
    herr_t ret_value = SUCCEED; /* Return value */
8156
8157
0
    FUNC_ENTER_PACKAGE
8158
8159
    /* Check if the corresponding VOL callback exists */
8160
0
    if (NULL == cls->optional)
8161
0
        HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'optional' method");
8162
8163
    /* Prepare & restore library for user callback */
8164
0
    H5_BEFORE_USER_CB(FAIL)
8165
0
        {
8166
            /* Call the corresponding VOL callback */
8167
0
            ret_value = (cls->optional)(obj, args, dxpl_id, req);
8168
0
        }
8169
0
    H5_AFTER_USER_CB(FAIL)
8170
0
    if (ret_value < 0)
8171
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback");
8172
8173
0
done:
8174
0
    FUNC_LEAVE_NOAPI(ret_value)
8175
0
} /* end H5VL__optional() */
8176
8177
/*-------------------------------------------------------------------------
8178
 * Function:    H5VL_optional
8179
 *
8180
 * Purpose:     Optional operation specific to connectors.
8181
 *
8182
 * Return:      Success:    Non-negative
8183
 *              Failure:    Negative
8184
 *
8185
 *-------------------------------------------------------------------------
8186
 */
8187
herr_t
8188
H5VL_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req)
8189
0
{
8190
0
    bool   vol_wrapper_set = false;   /* Whether the VOL object wrapping context was set up */
8191
0
    herr_t ret_value       = SUCCEED; /* Return value */
8192
8193
0
    FUNC_ENTER_NOAPI(FAIL)
8194
8195
    /* Set wrapper info in API context */
8196
0
    if (H5VL_set_vol_wrapper(vol_obj) < 0)
8197
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info");
8198
0
    vol_wrapper_set = true;
8199
8200
    /* Call the corresponding internal VOL routine */
8201
0
    if ((ret_value = H5VL__optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0)
8202
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback");
8203
8204
0
done:
8205
    /* Reset object wrapping info in API context */
8206
0
    if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
8207
0
        HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info");
8208
8209
0
    FUNC_LEAVE_NOAPI(ret_value)
8210
0
} /* end H5VL_optional() */
8211
8212
/*-------------------------------------------------------------------------
8213
 * Function:    H5VLoptional
8214
 *
8215
 * Purpose:     Performs an optional connector-specific operation
8216
 *
8217
 * Return:      Success:    Non-negative
8218
 *              Failure:    Negative
8219
 *
8220
 *-------------------------------------------------------------------------
8221
 */
8222
herr_t
8223
H5VLoptional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/)
8224
0
{
8225
0
    H5VL_connector_t *connector;           /* VOL connector */
8226
0
    herr_t            ret_value = SUCCEED; /* Return value */
8227
8228
0
    FUNC_ENTER_API_NOINIT
8229
8230
    /* Check args and get connector pointer */
8231
0
    if (NULL == obj)
8232
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object");
8233
0
    if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL)))
8234
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
8235
8236
    /* Call the corresponding internal VOL routine */
8237
0
    if ((ret_value = H5VL__optional(obj, connector->cls, args, dxpl_id, req)) < 0)
8238
0
        HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback");
8239
8240
0
done:
8241
0
    FUNC_LEAVE_API_NOINIT(ret_value)
8242
0
} /* end H5VLoptional() */