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 "H5Iprivate.h" /* IDs */ |
33 | | #include "H5Pprivate.h" /* Property lists */ |
34 | | #include "H5Tprivate.h" /* Datatypes */ |
35 | | #include "H5VLpkg.h" /* Virtual Object Layer */ |
36 | | |
37 | | /* VOL connectors */ |
38 | | #include "H5VLnative_private.h" /* Native VOL connector */ |
39 | | |
40 | | /****************/ |
41 | | /* Local Macros */ |
42 | | /****************/ |
43 | | |
44 | | /******************/ |
45 | | /* Local Typedefs */ |
46 | | /******************/ |
47 | | |
48 | | /********************/ |
49 | | /* Local Prototypes */ |
50 | | /********************/ |
51 | | |
52 | | /*********************/ |
53 | | /* Package Variables */ |
54 | | /*********************/ |
55 | | |
56 | | /*****************************/ |
57 | | /* Library Private Variables */ |
58 | | /*****************************/ |
59 | | |
60 | | /*******************/ |
61 | | /* Local Variables */ |
62 | | /*******************/ |
63 | | |
64 | | /*------------------------------------------------------------------------- |
65 | | * Function: H5VLregister_connector |
66 | | * |
67 | | * Purpose: Registers a new VOL connector as a member of the virtual object |
68 | | * layer class. |
69 | | * |
70 | | * VIPL_ID is a VOL initialization property list which must be |
71 | | * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT). |
72 | | * |
73 | | * Return: Success: A VOL connector ID which is good until the |
74 | | * library is closed or the connector is |
75 | | * unregistered. |
76 | | * |
77 | | * Failure: H5I_INVALID_HID |
78 | | * |
79 | | *------------------------------------------------------------------------- |
80 | | */ |
81 | | hid_t |
82 | | H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id) |
83 | 0 | { |
84 | 0 | H5VL_connector_t *connector = NULL; |
85 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
86 | |
|
87 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
88 | | |
89 | | /* Check VOL initialization property list */ |
90 | 0 | if (H5P_DEFAULT == vipl_id) |
91 | 0 | vipl_id = H5P_VOL_INITIALIZE_DEFAULT; |
92 | 0 | else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE)) |
93 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list"); |
94 | | |
95 | | /* Register connector */ |
96 | 0 | if (NULL == (connector = H5VL__register_connector_by_class(cls, vipl_id))) |
97 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL class"); |
98 | | |
99 | | /* Get ID for connector */ |
100 | 0 | if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0) |
101 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector"); |
102 | | |
103 | 0 | done: |
104 | 0 | if (ret_value < 0) |
105 | | /* Decrement refcount on connector */ |
106 | 0 | if (connector && H5VL_conn_dec_rc(connector) < 0) |
107 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, |
108 | 0 | "unable to decrement ref count on VOL connector"); |
109 | |
|
110 | 0 | FUNC_LEAVE_API(ret_value) |
111 | 0 | } /* end H5VLregister_connector() */ |
112 | | |
113 | | /*------------------------------------------------------------------------- |
114 | | * Function: H5VLregister_connector_by_name |
115 | | * |
116 | | * Purpose: Registers a new VOL connector as a member of the virtual object |
117 | | * layer class. |
118 | | * |
119 | | * VIPL_ID is a VOL initialization property list which must be |
120 | | * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT). |
121 | | * |
122 | | * Return: Success: A VOL connector ID which is good until the |
123 | | * library is closed or the connector is |
124 | | * unregistered. |
125 | | * |
126 | | * Failure: H5I_INVALID_HID |
127 | | * |
128 | | *------------------------------------------------------------------------- |
129 | | */ |
130 | | hid_t |
131 | | H5VLregister_connector_by_name(const char *name, hid_t vipl_id) |
132 | 0 | { |
133 | 0 | H5VL_connector_t *connector = NULL; |
134 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
135 | |
|
136 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
137 | | |
138 | | /* Check arguments */ |
139 | 0 | if (!name) |
140 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "null VOL connector name is disallowed"); |
141 | 0 | if (0 == strlen(name)) |
142 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, |
143 | 0 | "zero-length VOL connector name is disallowed"); |
144 | | |
145 | | /* Check VOL initialization property list */ |
146 | 0 | if (H5P_DEFAULT == vipl_id) |
147 | 0 | vipl_id = H5P_VOL_INITIALIZE_DEFAULT; |
148 | 0 | else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE)) |
149 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list"); |
150 | | |
151 | | /* Register connector */ |
152 | 0 | if (NULL == (connector = H5VL__register_connector_by_name(name, vipl_id))) |
153 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector"); |
154 | | |
155 | | /* Get ID for connector */ |
156 | 0 | if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0) |
157 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID"); |
158 | | |
159 | 0 | done: |
160 | 0 | if (ret_value < 0) |
161 | | /* Decrement refcount on connector */ |
162 | 0 | if (connector && H5VL_conn_dec_rc(connector) < 0) |
163 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, |
164 | 0 | "unable to decrement ref count on VOL connector"); |
165 | |
|
166 | 0 | FUNC_LEAVE_API(ret_value) |
167 | 0 | } /* end H5VLregister_connector_by_name() */ |
168 | | |
169 | | /*------------------------------------------------------------------------- |
170 | | * Function: H5VLregister_connector_by_value |
171 | | * |
172 | | * Purpose: Registers a new VOL connector as a member of the virtual object |
173 | | * layer class. |
174 | | * |
175 | | * VIPL_ID is a VOL initialization property list which must be |
176 | | * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT). |
177 | | * |
178 | | * Return: Success: A VOL connector ID which is good until the |
179 | | * library is closed or the connector is |
180 | | * unregistered. |
181 | | * |
182 | | * Failure: H5I_INVALID_HID |
183 | | * |
184 | | *------------------------------------------------------------------------- |
185 | | */ |
186 | | hid_t |
187 | | H5VLregister_connector_by_value(H5VL_class_value_t value, hid_t vipl_id) |
188 | 0 | { |
189 | 0 | H5VL_connector_t *connector = NULL; |
190 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
191 | |
|
192 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
193 | | |
194 | | /* Check arguments */ |
195 | 0 | if (value < 0) |
196 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, |
197 | 0 | "negative VOL connector value is disallowed"); |
198 | | |
199 | | /* Check VOL initialization property list */ |
200 | 0 | if (H5P_DEFAULT == vipl_id) |
201 | 0 | vipl_id = H5P_VOL_INITIALIZE_DEFAULT; |
202 | 0 | else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE)) |
203 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list"); |
204 | | |
205 | | /* Register connector */ |
206 | 0 | if (NULL == (connector = H5VL__register_connector_by_value(value, vipl_id))) |
207 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector"); |
208 | | |
209 | | /* Get ID for connector */ |
210 | 0 | if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0) |
211 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID"); |
212 | | |
213 | 0 | done: |
214 | 0 | if (ret_value < 0) |
215 | | /* Decrement refcount on connector */ |
216 | 0 | if (connector && H5VL_conn_dec_rc(connector) < 0) |
217 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, |
218 | 0 | "unable to decrement ref count on VOL connector"); |
219 | |
|
220 | 0 | FUNC_LEAVE_API(ret_value) |
221 | 0 | } /* end H5VLregister_connector_by_value() */ |
222 | | |
223 | | /*------------------------------------------------------------------------- |
224 | | * Function: H5VLis_connector_registered_by_name |
225 | | * |
226 | | * Purpose: Tests whether a VOL class has been registered or not |
227 | | * according to a supplied connector name. |
228 | | * |
229 | | * Return: >0 if a VOL connector with that name has been registered |
230 | | * 0 if a VOL connector with that name has NOT been registered |
231 | | * <0 on errors |
232 | | * |
233 | | *------------------------------------------------------------------------- |
234 | | */ |
235 | | htri_t |
236 | | H5VLis_connector_registered_by_name(const char *name) |
237 | 0 | { |
238 | 0 | htri_t ret_value = false; /* Return value */ |
239 | |
|
240 | 0 | FUNC_ENTER_API(FAIL) |
241 | | |
242 | | /* Check if connector with this name is registered */ |
243 | 0 | if ((ret_value = H5VL__is_connector_registered_by_name(name)) < 0) |
244 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL"); |
245 | | |
246 | 0 | done: |
247 | 0 | FUNC_LEAVE_API(ret_value) |
248 | 0 | } /* end H5VLis_connector_registered_by_name() */ |
249 | | |
250 | | /*------------------------------------------------------------------------- |
251 | | * Function: H5VLis_connector_registered_by_value |
252 | | * |
253 | | * Purpose: Tests whether a VOL class has been registered or not |
254 | | * according to a supplied connector value (ID). |
255 | | * |
256 | | * Return: >0 if a VOL connector with that value has been registered |
257 | | * 0 if a VOL connector with that value hasn't been registered |
258 | | * <0 on errors |
259 | | * |
260 | | *------------------------------------------------------------------------- |
261 | | */ |
262 | | htri_t |
263 | | H5VLis_connector_registered_by_value(H5VL_class_value_t connector_value) |
264 | 0 | { |
265 | 0 | htri_t ret_value = false; |
266 | |
|
267 | 0 | FUNC_ENTER_API(FAIL) |
268 | | |
269 | | /* Check if connector with this value is registered */ |
270 | 0 | if ((ret_value = H5VL__is_connector_registered_by_value(connector_value)) < 0) |
271 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL"); |
272 | | |
273 | 0 | done: |
274 | 0 | FUNC_LEAVE_API(ret_value) |
275 | 0 | } /* end H5VLis_connector_registered_by_value() */ |
276 | | |
277 | | /*------------------------------------------------------------------------- |
278 | | * Function: H5VLget_connector_id |
279 | | * |
280 | | * Purpose: Retrieves the VOL connector ID for a given object ID. |
281 | | * |
282 | | * Return: A valid VOL connector ID. This ID will need to be closed |
283 | | * using H5VLclose(). |
284 | | * |
285 | | * H5I_INVALID_HID on error. |
286 | | * |
287 | | *------------------------------------------------------------------------- |
288 | | */ |
289 | | hid_t |
290 | | H5VLget_connector_id(hid_t obj_id) |
291 | 0 | { |
292 | 0 | H5VL_object_t *vol_obj = NULL; |
293 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
294 | |
|
295 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
296 | | |
297 | | /* Get the underlying VOL object for the object ID */ |
298 | 0 | if (NULL == (vol_obj = H5VL_vol_object(obj_id))) |
299 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier"); |
300 | | |
301 | | /* Register an ID for the connector */ |
302 | 0 | if ((ret_value = H5VL_conn_register(vol_obj->connector)) < 0) |
303 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't get VOL ID"); |
304 | | |
305 | 0 | done: |
306 | 0 | FUNC_LEAVE_API(ret_value) |
307 | 0 | } /* end H5VLget_connector_id() */ |
308 | | |
309 | | /*------------------------------------------------------------------------- |
310 | | * Function: H5VLget_connector_id_by_name |
311 | | * |
312 | | * Purpose: Retrieves the ID for a registered VOL connector. |
313 | | * |
314 | | * Return: A valid VOL connector ID if a connector by that name has |
315 | | * been registered. This ID will need to be closed using |
316 | | * H5VLclose(). |
317 | | * |
318 | | * H5I_INVALID_HID on error or if a VOL connector of that |
319 | | * name has not been registered. |
320 | | * |
321 | | *------------------------------------------------------------------------- |
322 | | */ |
323 | | hid_t |
324 | | H5VLget_connector_id_by_name(const char *name) |
325 | 0 | { |
326 | 0 | H5VL_connector_t *connector = NULL; |
327 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
328 | |
|
329 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
330 | | |
331 | | /* Get connector ID with this name */ |
332 | 0 | if (NULL == (connector = H5VL__get_connector_by_name(name))) |
333 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector"); |
334 | | |
335 | | /* Get ID for connector */ |
336 | 0 | if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0) |
337 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID"); |
338 | | |
339 | 0 | done: |
340 | 0 | if (ret_value < 0) |
341 | | /* Decrement refcount on connector */ |
342 | 0 | if (connector && H5VL_conn_dec_rc(connector) < 0) |
343 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, |
344 | 0 | "unable to decrement ref count on VOL connector"); |
345 | |
|
346 | 0 | FUNC_LEAVE_API(ret_value) |
347 | 0 | } /* end H5VLget_connector_id_by_name() */ |
348 | | |
349 | | /*------------------------------------------------------------------------- |
350 | | * Function: H5VLget_connector_id_by_value |
351 | | * |
352 | | * Purpose: Retrieves the ID for a registered VOL connector. |
353 | | * |
354 | | * Return: A valid VOL connector ID if a connector with that value has |
355 | | * been registered. This ID will need to be closed using |
356 | | * H5VLclose(). |
357 | | * |
358 | | * H5I_INVALID_HID on error or if a VOL connector with that |
359 | | * value has not been registered. |
360 | | * |
361 | | *------------------------------------------------------------------------- |
362 | | */ |
363 | | hid_t |
364 | | H5VLget_connector_id_by_value(H5VL_class_value_t connector_value) |
365 | 0 | { |
366 | 0 | H5VL_connector_t *connector = NULL; |
367 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
368 | |
|
369 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
370 | | |
371 | | /* Get connector ID with this value */ |
372 | 0 | if (NULL == (connector = H5VL__get_connector_by_value(connector_value))) |
373 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector"); |
374 | | |
375 | | /* Get ID for connector */ |
376 | 0 | if ((ret_value = H5I_register(H5I_VOL, connector, true)) < 0) |
377 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID"); |
378 | | |
379 | 0 | done: |
380 | 0 | if (ret_value < 0) |
381 | | /* Decrement refcount on connector */ |
382 | 0 | if (connector && H5VL_conn_dec_rc(connector) < 0) |
383 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, |
384 | 0 | "unable to decrement ref count on VOL connector"); |
385 | |
|
386 | 0 | FUNC_LEAVE_API(ret_value) |
387 | 0 | } /* end H5VLget_connector_id_by_value() */ |
388 | | |
389 | | /*------------------------------------------------------------------------- |
390 | | * Function: H5VLget_connector_name |
391 | | * |
392 | | * Purpose: Returns the connector name for the VOL associated with the |
393 | | * object or file ID. |
394 | | * |
395 | | * This works like other calls where the caller must provide a |
396 | | * buffer of the appropriate size for the library to fill in. |
397 | | * i.e., passing in a NULL pointer for NAME will return the |
398 | | * required size of the buffer. |
399 | | * |
400 | | * Return: Success: The length of the connector name |
401 | | * |
402 | | * Failure: Negative |
403 | | * |
404 | | *------------------------------------------------------------------------- |
405 | | */ |
406 | | ssize_t |
407 | | H5VLget_connector_name(hid_t obj_id, char *name /*out*/, size_t size) |
408 | 0 | { |
409 | 0 | H5VL_object_t *vol_obj; |
410 | 0 | ssize_t ret_value = -1; |
411 | |
|
412 | 0 | FUNC_ENTER_API(FAIL) |
413 | | |
414 | | /* Get the object pointer */ |
415 | 0 | if (NULL == (vol_obj = H5VL_vol_object(obj_id))) |
416 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid VOL identifier"); |
417 | | |
418 | | /* Call internal routine */ |
419 | 0 | ret_value = (ssize_t)H5VL__get_connector_name(vol_obj->connector, name, size); |
420 | |
|
421 | 0 | done: |
422 | 0 | FUNC_LEAVE_API(ret_value) |
423 | 0 | } /* end H5VLget_connector_name() */ |
424 | | |
425 | | /*------------------------------------------------------------------------- |
426 | | * Function: H5VLclose |
427 | | * |
428 | | * Purpose: Closes a VOL connector ID. This in no way affects |
429 | | * file access property lists which have been defined to use |
430 | | * this VOL connector or files which are already opened under with |
431 | | * this connector. |
432 | | * |
433 | | * Return: Success: Non-negative |
434 | | * Failure: Negative |
435 | | * |
436 | | *------------------------------------------------------------------------- |
437 | | */ |
438 | | herr_t |
439 | | H5VLclose(hid_t vol_id) |
440 | 0 | { |
441 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
442 | |
|
443 | 0 | FUNC_ENTER_API(FAIL) |
444 | | |
445 | | /* Check args */ |
446 | 0 | if (NULL == H5I_object_verify(vol_id, H5I_VOL)) |
447 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector"); |
448 | | |
449 | | /* Decrement the ref count on the ID, possibly releasing the VOL connector */ |
450 | 0 | if (H5I_dec_app_ref(vol_id) < 0) |
451 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to close VOL connector ID"); |
452 | | |
453 | 0 | done: |
454 | 0 | FUNC_LEAVE_API(ret_value) |
455 | 0 | } /* end H5VLclose() */ |
456 | | |
457 | | /*------------------------------------------------------------------------- |
458 | | * Function: H5VLunregister_connector |
459 | | * |
460 | | * Purpose: Removes a VOL connector ID from the library. This in no way affects |
461 | | * file access property lists which have been defined to use |
462 | | * this VOL connector or files which are already opened under with |
463 | | * this connector. |
464 | | * |
465 | | * The native VOL connector cannot be unregistered and attempts |
466 | | * to do so are considered an error. |
467 | | * |
468 | | * Return: Success: Non-negative |
469 | | * Failure: Negative |
470 | | * |
471 | | *------------------------------------------------------------------------- |
472 | | */ |
473 | | herr_t |
474 | | H5VLunregister_connector(hid_t vol_id) |
475 | 0 | { |
476 | 0 | H5VL_connector_t *native, *connector; |
477 | 0 | int cmp_value; /* Comparison result */ |
478 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
479 | |
|
480 | 0 | FUNC_ENTER_API(FAIL) |
481 | | |
482 | | /* Check arguments */ |
483 | 0 | if (NULL == (connector = H5I_object_verify(vol_id, H5I_VOL))) |
484 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID"); |
485 | | |
486 | | /* For the time being, we disallow unregistering the native VOL connector */ |
487 | 0 | native = H5VL_NATIVE_conn_g; |
488 | 0 | if (H5VL_cmp_connector_cls(&cmp_value, connector->cls, native->cls) < 0) |
489 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector classes"); |
490 | 0 | if (0 == cmp_value) |
491 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "unregistering the native VOL connector is not allowed"); |
492 | | |
493 | | /* The H5VL_connector_t struct will be freed by this function */ |
494 | 0 | if (H5I_dec_app_ref(vol_id) < 0) |
495 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to unregister VOL connector"); |
496 | | |
497 | 0 | done: |
498 | 0 | FUNC_LEAVE_API(ret_value) |
499 | 0 | } /* end H5VLunregister_connector() */ |
500 | | |
501 | | /*--------------------------------------------------------------------------- |
502 | | * Function: H5VLcmp_connector_cls |
503 | | * |
504 | | * Purpose: Compares two connector classes (based on their value field) |
505 | | * |
506 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
507 | | * _not_ part of the public API for HDF5 application developers. |
508 | | * |
509 | | * Return: Success: Non-negative, *cmp set to a value like strcmp |
510 | | * |
511 | | * Failure: Negative, *cmp unset |
512 | | * |
513 | | *--------------------------------------------------------------------------- |
514 | | */ |
515 | | herr_t |
516 | | H5VLcmp_connector_cls(int *cmp, hid_t connector_id1, hid_t connector_id2) |
517 | 0 | { |
518 | 0 | H5VL_connector_t *conn1, *conn2; /* Connectors for IDs */ |
519 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
520 | |
|
521 | 0 | FUNC_ENTER_API(FAIL) |
522 | | |
523 | | /* Check args and get class pointers */ |
524 | 0 | if (NULL == (conn1 = H5I_object_verify(connector_id1, H5I_VOL))) |
525 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID"); |
526 | 0 | if (NULL == (conn2 = H5I_object_verify(connector_id2, H5I_VOL))) |
527 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID"); |
528 | | |
529 | | /* Compare the two VOL connector classes */ |
530 | 0 | if (H5VL_cmp_connector_cls(cmp, conn1->cls, conn2->cls) < 0) |
531 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector classes"); |
532 | | |
533 | 0 | done: |
534 | 0 | FUNC_LEAVE_API(ret_value) |
535 | 0 | } /* H5VLcmp_connector_cls() */ |
536 | | |
537 | | /*--------------------------------------------------------------------------- |
538 | | * Function: H5VLwrap_register |
539 | | * |
540 | | * Purpose: Wrap an internal object with a "wrap context" and register an |
541 | | * hid_t for the resulting object. |
542 | | * |
543 | | * Note: This routine is mainly targeted toward wrapping objects for |
544 | | * iteration routine callbacks (i.e. the callbacks from H5Aiterate*, |
545 | | * H5Literate* / H5Lvisit*, and H5Ovisit* ). |
546 | | * |
547 | | * type must be a VOL-managed object class (H5I_FILE, |
548 | | * H5I_GROUP, H5I_DATATYPE, H5I_DATASET, H5I_MAP, or H5I_ATTR). |
549 | | * |
550 | | * Return: Success: Non-negative hid_t for the object. |
551 | | * Failure: Negative (H5I_INVALID_HID) |
552 | | * |
553 | | *--------------------------------------------------------------------------- |
554 | | */ |
555 | | hid_t |
556 | | H5VLwrap_register(void *obj, H5I_type_t type) |
557 | 0 | { |
558 | 0 | hid_t ret_value; /* Return value */ |
559 | | |
560 | | /* Use FUNC_ENTER_API_NOINIT here, so the API context doesn't get reset */ |
561 | 0 | FUNC_ENTER_API_NOINIT |
562 | | |
563 | | /* Check args */ |
564 | | /* Use a switch here for (hopefully) better performance than a series of |
565 | | * equality checks. We could also group these types together in H5I_type_t, |
566 | | * make some assertions here to guarantee that, then just check the range. |
567 | | */ |
568 | 0 | switch (type) { |
569 | 0 | case H5I_FILE: |
570 | 0 | case H5I_GROUP: |
571 | 0 | case H5I_DATATYPE: |
572 | 0 | case H5I_DATASET: |
573 | 0 | case H5I_MAP: |
574 | 0 | case H5I_ATTR: |
575 | | /* VOL-managed objects, call is valid */ |
576 | 0 | break; |
577 | 0 | case H5I_UNINIT: |
578 | 0 | case H5I_BADID: |
579 | 0 | case H5I_DATASPACE: |
580 | 0 | case H5I_VFL: |
581 | 0 | case H5I_VOL: |
582 | 0 | case H5I_GENPROP_CLS: |
583 | 0 | case H5I_GENPROP_LST: |
584 | 0 | case H5I_ERROR_CLASS: |
585 | 0 | case H5I_ERROR_MSG: |
586 | 0 | case H5I_ERROR_STACK: |
587 | 0 | case H5I_SPACE_SEL_ITER: |
588 | 0 | case H5I_EVENTSET: |
589 | 0 | case H5I_NTYPES: |
590 | 0 | default: |
591 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADRANGE, H5I_INVALID_HID, "invalid type number"); |
592 | 0 | } /* end switch */ |
593 | 0 | if (NULL == obj) |
594 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, H5I_INVALID_HID, "obj is NULL"); |
595 | | |
596 | | /* Wrap the object and register an ID for it */ |
597 | 0 | if ((ret_value = H5VL_wrap_register(type, obj, true)) < 0) |
598 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to wrap object"); |
599 | | |
600 | 0 | done: |
601 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
602 | 0 | } /* H5VLwrap_register() */ |
603 | | |
604 | | /*--------------------------------------------------------------------------- |
605 | | * Function: H5VLobject |
606 | | * |
607 | | * Purpose: Retrieve the object pointer associated with an hid_t for a |
608 | | * VOL object. |
609 | | * |
610 | | * Note: This routine is mainly targeted toward unwrapping objects for |
611 | | * testing. |
612 | | * |
613 | | * Return: Success: Object pointer |
614 | | * Failure: NULL |
615 | | * |
616 | | *--------------------------------------------------------------------------- |
617 | | */ |
618 | | void * |
619 | | H5VLobject(hid_t id) |
620 | 0 | { |
621 | 0 | void *ret_value; /* Return value */ |
622 | |
|
623 | 0 | FUNC_ENTER_API(NULL) |
624 | | |
625 | | /* Retrieve the object pointer for the ID */ |
626 | 0 | if (NULL == (ret_value = H5VL_object(id))) |
627 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to retrieve object"); |
628 | | |
629 | 0 | done: |
630 | 0 | FUNC_LEAVE_API(ret_value) |
631 | 0 | } /* H5VLobject() */ |
632 | | |
633 | | /*--------------------------------------------------------------------------- |
634 | | * Function: H5VLobject_is_native |
635 | | * |
636 | | * Purpose: Determines whether an object ID represents a native VOL |
637 | | * connector object. |
638 | | * |
639 | | * Return: Non-negative on success/Negative on failure |
640 | | * |
641 | | *--------------------------------------------------------------------------- |
642 | | */ |
643 | | herr_t |
644 | | H5VLobject_is_native(hid_t obj_id, bool *is_native) |
645 | 0 | { |
646 | 0 | H5VL_object_t *vol_obj = NULL; |
647 | 0 | herr_t ret_value = SUCCEED; |
648 | |
|
649 | 0 | FUNC_ENTER_API(FAIL) |
650 | |
|
651 | 0 | if (!is_native) |
652 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "`is_native` argument is NULL"); |
653 | | |
654 | | /* Get the location object for the ID */ |
655 | 0 | if (NULL == (vol_obj = H5VL_vol_object(obj_id))) |
656 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier"); |
657 | | |
658 | 0 | if (H5VL_object_is_native(vol_obj, is_native) < 0) |
659 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if object is a native connector object"); |
660 | | |
661 | 0 | done: |
662 | 0 | FUNC_LEAVE_API(ret_value) |
663 | 0 | } /* H5VLobject_is_native() */ |
664 | | |
665 | | /*------------------------------------------------------------------------- |
666 | | * Function: H5VLget_file_type |
667 | | * |
668 | | * Purpose: Returns a copy of dtype_id with its location set to be in |
669 | | * the file, with updated size, etc. |
670 | | * |
671 | | * Return: Non-negative on success/Negative on failure |
672 | | * |
673 | | *------------------------------------------------------------------------- |
674 | | */ |
675 | | hid_t |
676 | | H5VLget_file_type(void *file_obj, hid_t connector_id, hid_t dtype_id) |
677 | 0 | { |
678 | 0 | H5T_t *dtype; /* unregistered type */ |
679 | 0 | H5T_t *file_type = NULL; /* copied file type */ |
680 | 0 | hid_t file_type_id = -1; /* copied file type id */ |
681 | 0 | H5VL_connector_t *connector; /* VOL connector */ |
682 | 0 | H5VL_object_t *file_vol_obj = NULL; /* VOL object for file */ |
683 | 0 | hid_t ret_value = -1; /* Return value */ |
684 | |
|
685 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
686 | | |
687 | | /* Check args */ |
688 | 0 | if (!file_obj) |
689 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "no file object supplied"); |
690 | 0 | if (NULL == (dtype = H5I_object_verify(dtype_id, H5I_DATATYPE))) |
691 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); |
692 | 0 | if (NULL == (connector = H5I_object_verify(connector_id, H5I_VOL))) |
693 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file VOL ID"); |
694 | | |
695 | | /* Create VOL object for file if necessary (force_conv will be true if and |
696 | | * only if file needs to be passed to H5T_set_loc) */ |
697 | 0 | if (H5T_GET_FORCE_CONV(dtype)) |
698 | 0 | if (NULL == (file_vol_obj = H5VL_new_vol_obj(H5I_FILE, file_obj, connector, true))) |
699 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create VOL object"); |
700 | | |
701 | | /* Copy the datatype */ |
702 | 0 | if (NULL == (file_type = H5T_copy(dtype, H5T_COPY_TRANSIENT))) |
703 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, H5I_INVALID_HID, "unable to copy datatype"); |
704 | | |
705 | | /* Register file type id */ |
706 | 0 | if ((file_type_id = H5I_register(H5I_DATATYPE, file_type, false)) < 0) { |
707 | 0 | (void)H5T_close_real(file_type); |
708 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file datatype"); |
709 | 0 | } /* end if */ |
710 | | |
711 | | /* Set the location of the datatype to be in the file */ |
712 | 0 | if (H5T_set_loc(file_type, file_vol_obj, H5T_LOC_DISK) < 0) |
713 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "can't set datatype location"); |
714 | | |
715 | | /* Release our reference to file_type */ |
716 | 0 | if (file_vol_obj) { |
717 | 0 | if (H5VL_free_object(file_vol_obj) < 0) |
718 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to free VOL object"); |
719 | 0 | file_vol_obj = NULL; |
720 | 0 | } /* end if */ |
721 | | |
722 | | /* Set return value */ |
723 | 0 | ret_value = file_type_id; |
724 | |
|
725 | 0 | done: |
726 | | /* Cleanup on error */ |
727 | 0 | if (ret_value < 0) { |
728 | 0 | if (file_vol_obj && H5VL_free_object(file_vol_obj) < 0) |
729 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to free VOL object"); |
730 | 0 | if (file_type_id >= 0 && H5I_dec_ref(file_type_id) < 0) |
731 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, "unable to close file datatype"); |
732 | 0 | } /* end if */ |
733 | |
|
734 | 0 | FUNC_LEAVE_API(ret_value) |
735 | 0 | } /* end H5VLget_file_type() */ |
736 | | |
737 | | /*--------------------------------------------------------------------------- |
738 | | * Function: H5VLretrieve_lib_state |
739 | | * |
740 | | * Purpose: Retrieves a copy of the internal state of the HDF5 library, |
741 | | * so that it can be restored later. |
742 | | * |
743 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
744 | | * _not_ part of the public API for HDF5 application developers. |
745 | | * |
746 | | * Return: Success: Non-negative, *state set |
747 | | * Failure: Negative, *state unset |
748 | | * |
749 | | *--------------------------------------------------------------------------- |
750 | | */ |
751 | | herr_t |
752 | | H5VLretrieve_lib_state(void **state /*out*/) |
753 | 0 | { |
754 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
755 | | |
756 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
757 | 0 | FUNC_ENTER_API_NOINIT |
758 | | |
759 | | /* Check args */ |
760 | 0 | if (NULL == state) |
761 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer"); |
762 | | |
763 | | /* Retrieve the library state */ |
764 | 0 | if (H5VL_retrieve_lib_state(state) < 0) |
765 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve library state"); |
766 | | |
767 | 0 | done: |
768 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
769 | 0 | } /* H5VLretrieve_lib_state() */ |
770 | | |
771 | | herr_t |
772 | | H5VLopen_lib_context(void **context) |
773 | 0 | { |
774 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
775 | | |
776 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
777 | 0 | FUNC_ENTER_API_NOINIT |
778 | | |
779 | | /* Check args */ |
780 | 0 | if (NULL == context) |
781 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid context pointer"); |
782 | | |
783 | | /* Start a new library state */ |
784 | 0 | if (H5VL_start_lib_state(context) < 0) |
785 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't start new library state"); |
786 | | |
787 | 0 | done: |
788 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
789 | 0 | } /* H5VLopen_lib_context() */ |
790 | | |
791 | | /*--------------------------------------------------------------------------- |
792 | | * Function: H5VLrestore_lib_state |
793 | | * |
794 | | * Purpose: Restores the internal state of the HDF5 library. |
795 | | * |
796 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
797 | | * _not_ part of the public API for HDF5 application developers. |
798 | | * |
799 | | * Return: Success: Non-negative |
800 | | * Failure: Negative |
801 | | * |
802 | | *--------------------------------------------------------------------------- |
803 | | */ |
804 | | herr_t |
805 | | H5VLrestore_lib_state(const void *state) |
806 | 0 | { |
807 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
808 | | |
809 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
810 | 0 | FUNC_ENTER_API_NOINIT |
811 | | |
812 | | /* Check args */ |
813 | 0 | if (NULL == state) |
814 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer"); |
815 | | |
816 | | /* Restore the library state */ |
817 | 0 | if (H5VL_restore_lib_state(state) < 0) |
818 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't restore library state"); |
819 | | |
820 | 0 | done: |
821 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
822 | 0 | } /* H5VLrestore_lib_state() */ |
823 | | |
824 | | herr_t |
825 | | H5VLclose_lib_context(void *context) |
826 | 0 | { |
827 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
828 | | |
829 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
830 | 0 | FUNC_ENTER_API_NOINIT |
831 | | |
832 | | /* Check args */ |
833 | 0 | if (NULL == context) |
834 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid context pointer"); |
835 | | |
836 | | /* Reset the library state */ |
837 | 0 | if (H5VL_finish_lib_state(context) < 0) |
838 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset library state"); |
839 | | |
840 | 0 | done: |
841 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
842 | 0 | } /* H5VLclose_lib_context() */ |
843 | | |
844 | | /*--------------------------------------------------------------------------- |
845 | | * Function: H5VLfree_lib_state |
846 | | * |
847 | | * Purpose: Free a retrieved library state. |
848 | | * |
849 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
850 | | * _not_ part of the public API for HDF5 application developers. |
851 | | * |
852 | | * Note: This routine must be called as a "pair" with |
853 | | * H5VLretrieve_lib_state. |
854 | | * |
855 | | * Return: Success: Non-negative |
856 | | * Failure: Negative |
857 | | * |
858 | | *--------------------------------------------------------------------------- |
859 | | */ |
860 | | herr_t |
861 | | H5VLfree_lib_state(void *state) |
862 | 0 | { |
863 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
864 | |
|
865 | 0 | FUNC_ENTER_API(FAIL) |
866 | | |
867 | | /* Check args */ |
868 | 0 | if (NULL == state) |
869 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid state pointer"); |
870 | | |
871 | | /* Free the library state */ |
872 | 0 | if (H5VL_free_lib_state(state) < 0) |
873 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free library state"); |
874 | | |
875 | 0 | done: |
876 | 0 | FUNC_LEAVE_API(ret_value) |
877 | 0 | } /* H5VLfree_lib_state() */ |
878 | | |
879 | | /*--------------------------------------------------------------------------- |
880 | | * Function: H5VLquery_optional |
881 | | * |
882 | | * Purpose: Determine if a VOL connector supports a particular optional |
883 | | * callback operation, and a general sense of the operation's |
884 | | * behavior. |
885 | | * |
886 | | * Return: Success: Non-negative |
887 | | * Failure: Negative |
888 | | * |
889 | | *--------------------------------------------------------------------------- |
890 | | */ |
891 | | herr_t |
892 | | H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags /*out*/) |
893 | 0 | { |
894 | 0 | H5VL_object_t *vol_obj = NULL; |
895 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
896 | |
|
897 | 0 | FUNC_ENTER_API(FAIL) |
898 | | |
899 | | /* Check args */ |
900 | 0 | if (NULL == flags) |
901 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid 'flags' pointer"); |
902 | 0 | if (NULL == (vol_obj = H5VL_vol_object(obj_id))) |
903 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier"); |
904 | | |
905 | | /* Query the connector */ |
906 | 0 | if (H5VL_introspect_opt_query(vol_obj, subcls, opt_type, flags) < 0) |
907 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to query VOL connector operation"); |
908 | | |
909 | 0 | done: |
910 | 0 | FUNC_LEAVE_API(ret_value) |
911 | 0 | } /* H5VLquery_optional() */ |
912 | | |
913 | | /*--------------------------------------------------------------------------- |
914 | | * Function: H5VLregister_opt_operation |
915 | | * |
916 | | * Purpose: Allow a VOL connector to register a new optional operation |
917 | | * for a VOL object subclass. The operation name must be runtime |
918 | | * unique for each operation, preferably avoiding naming clashes |
919 | | * by using a Uniform Type Identifier (UTI, |
920 | | *https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html) |
921 | | * for each operation name. The value returned in the 'op_val' |
922 | | * pointer will be unique for that VOL connector to use for its |
923 | | * operation on that subclass. |
924 | | * |
925 | | * For example, registering a 'prefetch' operation for the |
926 | | * caching VOL connector written at the ALCF at Argonne National |
927 | | * Laboratory could have a UTI of: "gov.anl.alcf.cache.prefetch", |
928 | | * and the "evict" operation for the same connector could have a |
929 | | * UTI of: "gov.anl.alcf.cache.evict". Registering a "suspend |
930 | | * background threads" operation for the asynchronous VOL connector |
931 | | * written at NERSC at Lawrence Berkeley National Laboratory could |
932 | | * have a UTI of: "gov.lbnl.nersc.async.suspend_bkg_threads". |
933 | | * |
934 | | * Note: The first 1024 values of each subclass's optional operations |
935 | | * are reserved for the native VOL connector's use. |
936 | | * |
937 | | * Return: Success: Non-negative |
938 | | * Failure: Negative |
939 | | * |
940 | | *--------------------------------------------------------------------------- |
941 | | */ |
942 | | herr_t |
943 | | H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) |
944 | 0 | { |
945 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
946 | |
|
947 | 0 | FUNC_ENTER_API(FAIL) |
948 | | |
949 | | /* Check args */ |
950 | 0 | if (NULL == op_val) |
951 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer"); |
952 | 0 | if (NULL == op_name) |
953 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer"); |
954 | 0 | if ('\0' == *op_name) |
955 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string"); |
956 | 0 | if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || |
957 | 0 | (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || |
958 | 0 | (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) |
959 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type"); |
960 | | |
961 | | /* Register the operation */ |
962 | 0 | if (H5VL__register_opt_operation(subcls, op_name, op_val) < 0) |
963 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register dynamic optional operation: '%s'", |
964 | 0 | op_name); |
965 | | |
966 | 0 | done: |
967 | 0 | FUNC_LEAVE_API(ret_value) |
968 | 0 | } /* H5VLregister_opt_operation() */ |
969 | | |
970 | | /*--------------------------------------------------------------------------- |
971 | | * Function: H5VLfind_opt_operation |
972 | | * |
973 | | * Purpose: Look up a optional operation for a VOL object subclass, by name. |
974 | | * |
975 | | * Return: Success: Non-negative |
976 | | * Failure: Negative |
977 | | * |
978 | | *--------------------------------------------------------------------------- |
979 | | */ |
980 | | herr_t |
981 | | H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) |
982 | 0 | { |
983 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
984 | |
|
985 | 0 | FUNC_ENTER_API(FAIL) |
986 | | |
987 | | /* Check args */ |
988 | 0 | if (NULL == op_val) |
989 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer"); |
990 | 0 | if (NULL == op_name) |
991 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer"); |
992 | 0 | if ('\0' == *op_name) |
993 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string"); |
994 | 0 | if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || |
995 | 0 | (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || |
996 | 0 | (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) |
997 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type"); |
998 | | |
999 | | /* Find the operation */ |
1000 | 0 | if (H5VL__find_opt_operation(subcls, op_name, op_val) < 0) |
1001 | 0 | HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "can't find dynamic optional operation: '%s'", op_name); |
1002 | | |
1003 | 0 | done: |
1004 | 0 | FUNC_LEAVE_API(ret_value) |
1005 | 0 | } /* H5VLfind_opt_operation() */ |
1006 | | |
1007 | | /*--------------------------------------------------------------------------- |
1008 | | * Function: H5VLunregister_opt_operation |
1009 | | * |
1010 | | * Purpose: Unregister a optional operation for a VOL object subclass, by name. |
1011 | | * |
1012 | | * Return: Success: Non-negative |
1013 | | * Failure: Negative |
1014 | | * |
1015 | | *--------------------------------------------------------------------------- |
1016 | | */ |
1017 | | herr_t |
1018 | | H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name) |
1019 | 0 | { |
1020 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
1021 | |
|
1022 | 0 | FUNC_ENTER_API(FAIL) |
1023 | | |
1024 | | /* Check args */ |
1025 | 0 | if (NULL == op_name) |
1026 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer"); |
1027 | 0 | if ('\0' == *op_name) |
1028 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string"); |
1029 | 0 | if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || |
1030 | 0 | (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || |
1031 | 0 | (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) |
1032 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type"); |
1033 | | |
1034 | | /* Unregister the operation */ |
1035 | 0 | if (H5VL__unregister_opt_operation(subcls, op_name) < 0) |
1036 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "can't unregister dynamic optional operation: '%s'", |
1037 | 0 | op_name); |
1038 | | |
1039 | 0 | done: |
1040 | | FUNC_LEAVE_API(ret_value) |
1041 | 0 | } /* H5VLunregister_opt_operation() */ |