Coverage Report

Created: 2026-02-26 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5VLdyn_ops.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 "H5FLprivate.h" /* Free lists                           */
33
#include "H5MMprivate.h" /* Memory management                    */
34
#include "H5SLprivate.h" /* Skip lists         */
35
#include "H5VLpkg.h"     /* Virtual Object Layer                 */
36
37
/****************/
38
/* Local Macros */
39
/****************/
40
41
/******************/
42
/* Local Typedefs */
43
/******************/
44
45
/* Dynamic operation info */
46
typedef struct H5VL_dyn_op_t {
47
    char *op_name; /* Name of operation */
48
    int   op_val;  /* Value of operation */
49
} H5VL_dyn_op_t;
50
51
/********************/
52
/* Local Prototypes */
53
/********************/
54
static void H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op);
55
56
/*********************/
57
/* Package Variables */
58
/*********************/
59
60
/*****************************/
61
/* Library Private Variables */
62
/*****************************/
63
64
/*******************/
65
/* Local Variables */
66
/*******************/
67
68
/* The current optional operation values */
69
static int H5VL_opt_vals_g[H5VL_SUBCLS_TOKEN + 1] = {
70
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_NONE */
71
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_INFO */
72
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_WRAP */
73
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_ATTR */
74
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATASET */
75
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATATYPE */
76
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_FILE */
77
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_GROUP */
78
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_LINK */
79
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_OBJECT */
80
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_REQUEST */
81
    H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_BLOB */
82
    H5VL_RESERVED_NATIVE_OPTIONAL  /* H5VL_SUBCLS_TOKEN */
83
};
84
85
/* The current optional operations' info */
86
static H5SL_t *H5VL_opt_ops_g[H5VL_SUBCLS_TOKEN + 1] = {
87
    NULL, /* H5VL_SUBCLS_NONE */
88
    NULL, /* H5VL_SUBCLS_INFO */
89
    NULL, /* H5VL_SUBCLS_WRAP */
90
    NULL, /* H5VL_SUBCLS_ATTR */
91
    NULL, /* H5VL_SUBCLS_DATASET */
92
    NULL, /* H5VL_SUBCLS_DATATYPE */
93
    NULL, /* H5VL_SUBCLS_FILE */
94
    NULL, /* H5VL_SUBCLS_GROUP */
95
    NULL, /* H5VL_SUBCLS_LINK */
96
    NULL, /* H5VL_SUBCLS_OBJECT */
97
    NULL, /* H5VL_SUBCLS_REQUEST */
98
    NULL, /* H5VL_SUBCLS_BLOB */
99
    NULL  /* H5VL_SUBCLS_TOKEN */
100
};
101
102
/* Declare a free list to manage the H5VL_class_t struct */
103
H5FL_DEFINE_STATIC(H5VL_dyn_op_t);
104
105
/*---------------------------------------------------------------------------
106
 * Function:    H5VL__release_dyn_op
107
 *
108
 * Purpose:     Release a dynamic operation info node
109
 *
110
 * Return:      Success:    Non-negative
111
 *              Failure:    Negative
112
 *
113
 *---------------------------------------------------------------------------
114
 */
115
static void
116
H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op)
117
0
{
118
0
    FUNC_ENTER_PACKAGE_NOERR
119
120
0
    H5MM_xfree(dyn_op->op_name);
121
0
    H5FL_FREE(H5VL_dyn_op_t, dyn_op);
122
123
0
    FUNC_LEAVE_NOAPI_VOID
124
0
} /* H5VL__release_dyn_op() */
125
126
/*---------------------------------------------------------------------------
127
 * Function:    H5VL__term_opt_operation_cb
128
 *
129
 * Purpose:     Callback for releasing a dynamically registered operation info
130
 *
131
 * Return:      Success:    Non-negative
132
 *              Failure:    Negative
133
 *
134
 *---------------------------------------------------------------------------
135
 */
136
static herr_t
137
H5VL__term_opt_operation_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data)
138
0
{
139
0
    H5VL_dyn_op_t *item = (H5VL_dyn_op_t *)_item; /* Item to release */
140
141
0
    FUNC_ENTER_PACKAGE_NOERR
142
143
    /* Release the dynamically registered operation info */
144
0
    H5VL__release_dyn_op(item);
145
146
0
    FUNC_LEAVE_NOAPI(SUCCEED)
147
0
} /* H5VL__term_opt_operation_cb() */
148
149
/*---------------------------------------------------------------------------
150
 * Function:    H5VL__term_opt_operation
151
 *
152
 * Purpose:     Terminate the dynamically registered optional operations,
153
 *              releasing all operations.
154
 *
155
 * Return:      Success:    Non-negative
156
 *              Failure:    Negative
157
 *
158
 *---------------------------------------------------------------------------
159
 */
160
herr_t
161
H5VL__term_opt_operation(void)
162
0
{
163
0
    size_t subcls; /* Index over the elements of operation array */
164
165
0
    FUNC_ENTER_PACKAGE_NOERR
166
167
    /* Iterate over the VOL subclasses */
168
0
    for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++) {
169
0
        if (H5VL_opt_ops_g[subcls]) {
170
0
            H5SL_destroy(H5VL_opt_ops_g[subcls], H5VL__term_opt_operation_cb, NULL);
171
0
            H5VL_opt_ops_g[subcls] = NULL;
172
0
        }
173
0
    }
174
175
0
    FUNC_LEAVE_NOAPI(SUCCEED)
176
0
} /* H5VL__term_opt_operation() */
177
178
/*---------------------------------------------------------------------------
179
 * Function:    H5VL__register_opt_operation
180
 *
181
 * Purpose:     Register a new optional operation for a VOL object subclass.
182
 *
183
 * Return:      Success:    Non-negative
184
 *              Failure:    Negative
185
 *
186
 *---------------------------------------------------------------------------
187
 */
188
herr_t
189
H5VL__register_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val)
190
0
{
191
0
    H5VL_dyn_op_t *new_op;              /* Info about new operation */
192
0
    herr_t         ret_value = SUCCEED; /* Return value */
193
194
0
    FUNC_ENTER_PACKAGE
195
196
    /* Sanity checks */
197
0
    assert(op_val);
198
0
    assert(op_name && *op_name);
199
200
    /* Check for duplicate operation */
201
0
    if (H5VL_opt_ops_g[subcls]) {
202
0
        if (NULL != H5SL_search(H5VL_opt_ops_g[subcls], op_name))
203
0
            HGOTO_ERROR(H5E_VOL, H5E_EXISTS, FAIL, "operation name already exists");
204
0
    } /* end if */
205
0
    else {
206
        /* Create skip list for operation of this subclass */
207
0
        if (NULL == (H5VL_opt_ops_g[subcls] = H5SL_create(H5SL_TYPE_STR, NULL)))
208
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create skip list for operations");
209
0
    } /* end else */
210
211
    /* Register new operation */
212
0
    if (NULL == (new_op = H5FL_CALLOC(H5VL_dyn_op_t)))
213
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate memory for dynamic operation info");
214
0
    if (NULL == (new_op->op_name = H5MM_strdup(op_name)))
215
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate name for dynamic operation info");
216
0
    new_op->op_val = H5VL_opt_vals_g[subcls]++;
217
218
    /* Insert into subclass's skip list */
219
0
    if (H5SL_insert(H5VL_opt_ops_g[subcls], new_op, new_op->op_name) < 0)
220
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert operation info into skip list");
221
222
    /* Return the next operation value to the caller */
223
0
    *op_val = new_op->op_val;
224
225
0
done:
226
0
    FUNC_LEAVE_NOAPI(ret_value)
227
0
} /* H5VL__register_opt_operation() */
228
229
/*---------------------------------------------------------------------------
230
 * Function:    H5VL__num_opt_operation
231
 *
232
 * Purpose:     Returns the # of currently registered optional operations
233
 *
234
 * Return:      # of registered optional operations / <can't fail>
235
 *
236
 *---------------------------------------------------------------------------
237
 */
238
size_t
239
H5VL__num_opt_operation(void)
240
1
{
241
1
    size_t subcls;        /* Index over the elements of operation array */
242
1
    size_t ret_value = 0; /* Return value */
243
244
1
    FUNC_ENTER_PACKAGE_NOERR
245
246
    /* Iterate over the VOL subclasses */
247
14
    for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++)
248
13
        if (H5VL_opt_ops_g[subcls])
249
0
            ret_value += H5SL_count(H5VL_opt_ops_g[subcls]);
250
251
1
    FUNC_LEAVE_NOAPI(ret_value)
252
1
} /* H5VL__num_opt_operation() */
253
254
/*---------------------------------------------------------------------------
255
 * Function:    H5VL__find_opt_operation
256
 *
257
 * Purpose:     Look up a optional operation for a VOL object subclass, by name.
258
 *
259
 * Return:      Success:    Non-negative
260
 *              Failure:    Negative
261
 *
262
 *---------------------------------------------------------------------------
263
 */
264
herr_t
265
H5VL__find_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val)
266
0
{
267
0
    herr_t ret_value = SUCCEED; /* Return value */
268
269
0
    FUNC_ENTER_PACKAGE
270
271
    /* Sanity checks */
272
0
    assert(op_val);
273
0
    assert(op_name && *op_name);
274
275
    /* Check for dynamic operations in the VOL subclass */
276
0
    if (H5VL_opt_ops_g[subcls]) {
277
0
        H5VL_dyn_op_t *dyn_op; /* Info about operation */
278
279
        /* Search for dynamic operation with correct name */
280
0
        if (NULL == (dyn_op = H5SL_search(H5VL_opt_ops_g[subcls], op_name)))
281
0
            HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered");
282
283
        /* Set operation value for user */
284
0
        *op_val = dyn_op->op_val;
285
0
    } /* end if */
286
0
    else
287
0
        HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered");
288
289
0
done:
290
0
    FUNC_LEAVE_NOAPI(ret_value)
291
0
} /* H5VL__find_opt_operation() */
292
293
/*---------------------------------------------------------------------------
294
 * Function:    H5VL__unregister_opt_operation
295
 *
296
 * Purpose:     Unregister a optional operation for a VOL object subclass, by name.
297
 *
298
 * Return:      Success:    Non-negative
299
 *              Failure:    Negative
300
 *
301
 *---------------------------------------------------------------------------
302
 */
303
herr_t
304
H5VL__unregister_opt_operation(H5VL_subclass_t subcls, const char *op_name)
305
0
{
306
0
    herr_t ret_value = SUCCEED; /* Return value */
307
308
0
    FUNC_ENTER_PACKAGE
309
310
    /* Sanity checks */
311
0
    assert(op_name && *op_name);
312
313
    /* Check for dynamic operations in the VOL subclass */
314
0
    if (H5VL_opt_ops_g[subcls]) {
315
0
        H5VL_dyn_op_t *dyn_op; /* Info about operation */
316
317
        /* Search for dynamic operation with correct name */
318
0
        if (NULL == (dyn_op = H5SL_remove(H5VL_opt_ops_g[subcls], op_name)))
319
0
            HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered");
320
321
        /* Release the info for the operation */
322
0
        H5VL__release_dyn_op(dyn_op);
323
324
        /* Close the skip list, if no more operations in it */
325
0
        if (0 == H5SL_count(H5VL_opt_ops_g[subcls])) {
326
0
            if (H5SL_close(H5VL_opt_ops_g[subcls]) < 0)
327
0
                HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "can't close dyn op skip list");
328
0
            H5VL_opt_ops_g[subcls] = NULL;
329
0
        } /* end if */
330
0
    }     /* end if */
331
0
    else
332
0
        HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered");
333
334
0
done:
335
0
    FUNC_LEAVE_NOAPI(ret_value)
336
0
} /* H5VL__unregister_opt_operation() */