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 | | * H5I.c - Public routines for handling IDs |
15 | | */ |
16 | | |
17 | | /****************/ |
18 | | /* Module Setup */ |
19 | | /****************/ |
20 | | |
21 | | #include "H5Imodule.h" /* This source code file is part of the H5I module */ |
22 | | |
23 | | /***********/ |
24 | | /* Headers */ |
25 | | /***********/ |
26 | | #include "H5private.h" /* Generic Functions */ |
27 | | #include "H5Eprivate.h" /* Error handling */ |
28 | | #include "H5Fprivate.h" /* Files */ |
29 | | #include "H5Ipkg.h" /* IDs */ |
30 | | #include "H5MMprivate.h" /* Memory management */ |
31 | | #include "H5Pprivate.h" /* Property lists */ |
32 | | |
33 | | /****************/ |
34 | | /* Local Macros */ |
35 | | /****************/ |
36 | | |
37 | | /******************/ |
38 | | /* Local Typedefs */ |
39 | | /******************/ |
40 | | |
41 | | typedef struct { |
42 | | H5I_search_func_t app_cb; /* Application's callback routine */ |
43 | | void *app_key; /* Application's "key" (user data) */ |
44 | | void *ret_obj; /* Object to return */ |
45 | | } H5I_search_ud_t; |
46 | | |
47 | | typedef struct { |
48 | | H5I_iterate_func_t op; /* Application's callback routine */ |
49 | | void *op_data; /* Application's user data */ |
50 | | } H5I_iterate_pub_ud_t; |
51 | | |
52 | | /********************/ |
53 | | /* Package Typedefs */ |
54 | | /********************/ |
55 | | |
56 | | /********************/ |
57 | | /* Local Prototypes */ |
58 | | /********************/ |
59 | | |
60 | | static int H5I__search_cb(void *obj, hid_t id, void *_udata); |
61 | | static int H5I__iterate_pub_cb(void *obj, hid_t id, void *udata); |
62 | | |
63 | | /*********************/ |
64 | | /* Package Variables */ |
65 | | /*********************/ |
66 | | |
67 | | /*****************************/ |
68 | | /* Library Private Variables */ |
69 | | /*****************************/ |
70 | | |
71 | | /*******************/ |
72 | | /* Local Variables */ |
73 | | /*******************/ |
74 | | |
75 | | /*------------------------------------------------------------------------- |
76 | | * Function: H5Iregister_type2 |
77 | | * |
78 | | * Purpose: Public interface to H5I_register_type2. Creates a new type |
79 | | * of ID's to give out. A specific number (RESERVED) of type |
80 | | * entries may be reserved to enable "constant" values to be handed |
81 | | * out which are valid IDs in the type, but which do not map to any |
82 | | * data structures and are not allocated dynamically later. |
83 | | * FREE_FUNC is called with an object pointer when the object is |
84 | | * removed from the type. |
85 | | * |
86 | | * Return: Success: Type ID of the new type |
87 | | * Failure: H5I_BADID |
88 | | * |
89 | | *------------------------------------------------------------------------- |
90 | | */ |
91 | | H5I_type_t |
92 | | H5Iregister_type2(unsigned reserved, H5I_free_t free_func) |
93 | 0 | { |
94 | 0 | H5I_type_t ret_value = H5I_BADID; |
95 | |
|
96 | 0 | FUNC_ENTER_API(H5I_BADID) |
97 | |
|
98 | 0 | if (H5I_BADID == (ret_value = H5I__register_type_common(reserved, free_func))) |
99 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTINIT, H5I_BADID, "can't initialize ID class"); |
100 | | |
101 | 0 | done: |
102 | 0 | FUNC_LEAVE_API(ret_value) |
103 | 0 | } /* end H5Iregister_type2() */ |
104 | | |
105 | | /*------------------------------------------------------------------------- |
106 | | * Function: H5Itype_exists |
107 | | * |
108 | | * Purpose: Query function to inform the user if a given type is |
109 | | * currently registered with the library. |
110 | | * |
111 | | * Return: true/false/FAIL |
112 | | * |
113 | | *------------------------------------------------------------------------- |
114 | | */ |
115 | | htri_t |
116 | | H5Itype_exists(H5I_type_t type) |
117 | 0 | { |
118 | 0 | htri_t ret_value = true; /* Return value */ |
119 | |
|
120 | 0 | FUNC_ENTER_API(FAIL) |
121 | | |
122 | | /* Validate parameter */ |
123 | 0 | if (H5I_IS_LIB_TYPE(type)) |
124 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type"); |
125 | 0 | if (type <= H5I_BADID || (int)type >= H5I_next_type_g) |
126 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number"); |
127 | | |
128 | 0 | if (NULL == H5I_type_info_array_g[type]) |
129 | 0 | ret_value = false; |
130 | |
|
131 | 0 | done: |
132 | 0 | FUNC_LEAVE_API(ret_value) |
133 | 0 | } /* end H5Itype_exists() */ |
134 | | |
135 | | /*------------------------------------------------------------------------- |
136 | | * Function: H5Inmembers |
137 | | * |
138 | | * Purpose: Returns the number of members in a type. Public interface to |
139 | | * H5I_nmembers. The public interface throws an error if the |
140 | | * supplied type does not exist. This is different than the |
141 | | * private interface, which will just return 0. |
142 | | * |
143 | | * Return: SUCCEED/FAIL |
144 | | * |
145 | | *------------------------------------------------------------------------- |
146 | | */ |
147 | | herr_t |
148 | | H5Inmembers(H5I_type_t type, hsize_t *num_members) |
149 | 0 | { |
150 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
151 | |
|
152 | 0 | FUNC_ENTER_API(FAIL) |
153 | |
|
154 | 0 | if (H5I_IS_LIB_TYPE(type)) |
155 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type"); |
156 | | |
157 | | /* Validate parameters. This needs to be done here, instead of letting |
158 | | * the private interface handle it, because the public interface throws |
159 | | * an error when the supplied type does not exist. |
160 | | */ |
161 | 0 | if (type <= H5I_BADID || (int)type >= H5I_next_type_g) |
162 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number"); |
163 | 0 | if (NULL == H5I_type_info_array_g[type]) |
164 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "supplied type does not exist"); |
165 | | |
166 | 0 | if (num_members) { |
167 | 0 | int64_t members; |
168 | |
|
169 | 0 | if ((members = H5I_nmembers(type)) < 0) |
170 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTCOUNT, FAIL, "can't compute number of members"); |
171 | | |
172 | 0 | H5_CHECKED_ASSIGN(*num_members, hsize_t, members, int64_t); |
173 | 0 | } |
174 | | |
175 | 0 | done: |
176 | 0 | FUNC_LEAVE_API(ret_value) |
177 | 0 | } /* end H5Inmembers() */ |
178 | | |
179 | | /*------------------------------------------------------------------------- |
180 | | * Function: H5Iclear_type |
181 | | * |
182 | | * Purpose: Removes all objects from the type, calling the free |
183 | | * function for each object regardless of the reference count. |
184 | | * Public interface to H5I_clear_type. |
185 | | * |
186 | | * Return: SUCCEED/FAIL |
187 | | * |
188 | | *------------------------------------------------------------------------- |
189 | | */ |
190 | | herr_t |
191 | | H5Iclear_type(H5I_type_t type, bool force) |
192 | 0 | { |
193 | 0 | herr_t ret_value = FAIL; /* Return value */ |
194 | |
|
195 | 0 | FUNC_ENTER_API(FAIL) |
196 | |
|
197 | 0 | if (H5I_IS_LIB_TYPE(type)) |
198 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type"); |
199 | | |
200 | 0 | ret_value = H5I_clear_type(type, force, true); |
201 | |
|
202 | 0 | done: |
203 | 0 | FUNC_LEAVE_API(ret_value) |
204 | 0 | } /* end H5Iclear_type() */ |
205 | | |
206 | | /*------------------------------------------------------------------------- |
207 | | * Function: H5Idestroy_type |
208 | | * |
209 | | * Purpose: Destroys a type along with all IDs in that type |
210 | | * regardless of their reference counts. Destroying IDs |
211 | | * involves calling the free-func for each ID's object and |
212 | | * then adding the ID struct to the ID free list. Public |
213 | | * interface to H5I__destroy_type. |
214 | | * |
215 | | * Return: SUCCEED/FAIL |
216 | | * |
217 | | *------------------------------------------------------------------------- |
218 | | */ |
219 | | herr_t |
220 | | H5Idestroy_type(H5I_type_t type) |
221 | 0 | { |
222 | 0 | herr_t ret_value = FAIL; /* Return value */ |
223 | |
|
224 | 0 | FUNC_ENTER_API(FAIL) |
225 | |
|
226 | 0 | if (H5I_IS_LIB_TYPE(type)) |
227 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type"); |
228 | | |
229 | 0 | ret_value = H5I__destroy_type(type); |
230 | |
|
231 | 0 | done: |
232 | 0 | FUNC_LEAVE_API(ret_value) |
233 | 0 | } /* end H5Idestroy_type() */ |
234 | | |
235 | | /*------------------------------------------------------------------------- |
236 | | * Function: H5Iregister |
237 | | * |
238 | | * Purpose: Register an object. |
239 | | * |
240 | | * Return: Success: New object ID |
241 | | * Failure: H5I_INVALID_HID |
242 | | * |
243 | | *------------------------------------------------------------------------- |
244 | | */ |
245 | | hid_t |
246 | | H5Iregister(H5I_type_t type, const void *object) |
247 | 0 | { |
248 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
249 | |
|
250 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
251 | |
|
252 | 0 | if (H5I_IS_LIB_TYPE(type)) |
253 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, H5I_INVALID_HID, "cannot call public function on library type"); |
254 | | |
255 | | /* Register the object */ |
256 | 0 | if ((ret_value = H5I__register(type, object, true, NULL, NULL)) < 0) |
257 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object"); |
258 | | |
259 | 0 | done: |
260 | 0 | FUNC_LEAVE_API(ret_value) |
261 | 0 | } /* end H5Iregister() */ |
262 | | |
263 | | /*------------------------------------------------------------------------- |
264 | | * Function: H5Iregister_future |
265 | | * |
266 | | * Purpose: Register a "future" object. |
267 | | * |
268 | | * Return: Success: New future object ID |
269 | | * Failure: H5I_INVALID_HID |
270 | | * |
271 | | *------------------------------------------------------------------------- |
272 | | */ |
273 | | hid_t |
274 | | H5Iregister_future(H5I_type_t type, const void *object, H5I_future_realize_func_t realize_cb, |
275 | | H5I_future_discard_func_t discard_cb) |
276 | 0 | { |
277 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
278 | |
|
279 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
280 | | |
281 | | /* Check arguments */ |
282 | 0 | if (NULL == realize_cb) |
283 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADVALUE, H5I_INVALID_HID, "NULL pointer for realize_cb not allowed"); |
284 | 0 | if (NULL == discard_cb) |
285 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADVALUE, H5I_INVALID_HID, "NULL pointer for realize_cb not allowed"); |
286 | | |
287 | | /* Register the future object */ |
288 | 0 | if ((ret_value = H5I__register(type, object, true, realize_cb, discard_cb)) < 0) |
289 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object"); |
290 | | |
291 | 0 | done: |
292 | 0 | FUNC_LEAVE_API(ret_value) |
293 | 0 | } /* end H5Iregister_future() */ |
294 | | |
295 | | /*------------------------------------------------------------------------- |
296 | | * Function: H5Iobject_verify |
297 | | * |
298 | | * Purpose: Find an object pointer for the specified ID, verifying that |
299 | | * its in a particular type. Public interface to |
300 | | * H5I_object_verify. |
301 | | * |
302 | | * Return: Success: Non-NULL object pointer associated with the |
303 | | * specified ID. |
304 | | * Failure: NULL |
305 | | * |
306 | | *------------------------------------------------------------------------- |
307 | | */ |
308 | | void * |
309 | | H5Iobject_verify(hid_t id, H5I_type_t type) |
310 | 0 | { |
311 | 0 | void *ret_value = NULL; /* Return value */ |
312 | |
|
313 | 0 | FUNC_ENTER_API(NULL) |
314 | | |
315 | | /* Validate parameters */ |
316 | 0 | if (H5I_IS_LIB_TYPE(type)) |
317 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "cannot call public function on library type"); |
318 | 0 | if (type < 1 || (int)type >= H5I_next_type_g) |
319 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "identifier has invalid type"); |
320 | | |
321 | 0 | ret_value = H5I_object_verify(id, type); |
322 | |
|
323 | 0 | done: |
324 | 0 | FUNC_LEAVE_API(ret_value) |
325 | 0 | } /* end H5Iobject_verify() */ |
326 | | |
327 | | /*------------------------------------------------------------------------- |
328 | | * Function: H5Iget_type |
329 | | * |
330 | | * Purpose: The public version of H5I_get_type(), obtains a type number |
331 | | * when given an ID. The ID need not be the ID of an |
332 | | * object which currently exists because the type number is |
333 | | * encoded as part of the ID. |
334 | | * |
335 | | * Return: Success: A positive integer (corresponding to an H5I_type_t |
336 | | * enum value for library ID types, but not for user |
337 | | * ID types). |
338 | | * Failure: H5I_BADID |
339 | | * |
340 | | *------------------------------------------------------------------------- |
341 | | */ |
342 | | H5I_type_t |
343 | | H5Iget_type(hid_t id) |
344 | 303k | { |
345 | 303k | H5I_type_t ret_value = H5I_BADID; /* Return value */ |
346 | | |
347 | 607k | FUNC_ENTER_API(H5I_BADID) |
348 | | |
349 | 607k | ret_value = H5I_get_type(id); |
350 | | |
351 | 607k | if (ret_value <= H5I_BADID || (int)ret_value >= H5I_next_type_g || NULL == H5I_object(id)) |
352 | 0 | HGOTO_DONE(H5I_BADID); |
353 | | |
354 | 303k | done: |
355 | 303k | FUNC_LEAVE_API(ret_value) |
356 | 607k | } /* end H5Iget_type() */ |
357 | | |
358 | | /*------------------------------------------------------------------------- |
359 | | * Function: H5Iremove_verify |
360 | | * |
361 | | * Purpose: Removes the specified ID from its type, first checking that the |
362 | | * type of the ID and the type type are the same. Public interface to |
363 | | * H5I__remove_verify. |
364 | | * |
365 | | * Return: Success: A pointer to the object that was removed, the |
366 | | * same pointer which would have been found by |
367 | | * calling H5I_object(). |
368 | | * Failure: NULL |
369 | | * |
370 | | *------------------------------------------------------------------------- |
371 | | */ |
372 | | void * |
373 | | H5Iremove_verify(hid_t id, H5I_type_t type) |
374 | 0 | { |
375 | 0 | void *ret_value = NULL; /* Return value */ |
376 | |
|
377 | 0 | FUNC_ENTER_API(NULL) |
378 | |
|
379 | 0 | if (H5I_IS_LIB_TYPE(type)) |
380 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "cannot call public function on library type"); |
381 | | |
382 | | /* Remove the id */ |
383 | 0 | ret_value = H5I__remove_verify(id, type); |
384 | |
|
385 | 0 | done: |
386 | 0 | FUNC_LEAVE_API(ret_value) |
387 | 0 | } /* end H5Iremove_verify() */ |
388 | | |
389 | | /*------------------------------------------------------------------------- |
390 | | * Function: H5Idec_ref |
391 | | * |
392 | | * Purpose: Decrements the number of references outstanding for an ID. |
393 | | * If the reference count for an ID reaches zero, the object |
394 | | * will be closed. |
395 | | * |
396 | | * Return: Success: New reference count |
397 | | * Failure: -1 |
398 | | * |
399 | | *------------------------------------------------------------------------- |
400 | | */ |
401 | | int |
402 | | H5Idec_ref(hid_t id) |
403 | 0 | { |
404 | 0 | int ret_value = 0; /* Return value */ |
405 | |
|
406 | 0 | FUNC_ENTER_API((-1)) |
407 | | |
408 | | /* Check arguments */ |
409 | 0 | if (id < 0) |
410 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID"); |
411 | | |
412 | | /* Do actual decrement operation */ |
413 | 0 | if ((ret_value = H5I_dec_app_ref(id)) < 0) |
414 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't decrement ID ref count"); |
415 | | |
416 | 0 | done: |
417 | 0 | FUNC_LEAVE_API(ret_value) |
418 | 0 | } /* end H5Idec_ref() */ |
419 | | |
420 | | /*------------------------------------------------------------------------- |
421 | | * Function: H5Iinc_ref |
422 | | * |
423 | | * Purpose: Increments the number of references outstanding for an ID. |
424 | | * |
425 | | * Return: Success: New reference count |
426 | | * Failure: -1 |
427 | | * |
428 | | *------------------------------------------------------------------------- |
429 | | */ |
430 | | int |
431 | | H5Iinc_ref(hid_t id) |
432 | 70.6k | { |
433 | 70.6k | int ret_value = -1; /* Return value */ |
434 | | |
435 | 141k | FUNC_ENTER_API((-1)) |
436 | | |
437 | | /* Check arguments */ |
438 | 141k | if (id < 0) |
439 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID"); |
440 | | |
441 | | /* Do actual increment operation */ |
442 | 70.6k | if ((ret_value = H5I_inc_ref(id, true)) < 0) |
443 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTINC, (-1), "can't increment ID ref count"); |
444 | | |
445 | 70.6k | done: |
446 | 70.6k | FUNC_LEAVE_API(ret_value) |
447 | 70.6k | } /* end H5Iinc_ref() */ |
448 | | |
449 | | /*------------------------------------------------------------------------- |
450 | | * Function: H5Iget_ref |
451 | | * |
452 | | * Purpose: Retrieves the number of references outstanding for an ID. |
453 | | * |
454 | | * Return: Success: Reference count |
455 | | * Failure: -1 |
456 | | * |
457 | | *------------------------------------------------------------------------- |
458 | | */ |
459 | | int |
460 | | H5Iget_ref(hid_t id) |
461 | 0 | { |
462 | 0 | int ret_value = -1; /* Return value */ |
463 | |
|
464 | 0 | FUNC_ENTER_API((-1)) |
465 | | |
466 | | /* Check arguments */ |
467 | 0 | if (id < 0) |
468 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID"); |
469 | | |
470 | | /* Do actual retrieve operation */ |
471 | 0 | if ((ret_value = H5I_get_ref(id, true)) < 0) |
472 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't get ID ref count"); |
473 | | |
474 | 0 | done: |
475 | 0 | FUNC_LEAVE_API(ret_value) |
476 | 0 | } /* end H5Iget_ref() */ |
477 | | |
478 | | /*------------------------------------------------------------------------- |
479 | | * Function: H5Iinc_type_ref |
480 | | * |
481 | | * Purpose: Increments the number of references outstanding for an ID type. |
482 | | * |
483 | | * Return: Success: New reference count |
484 | | * Failure: -1 |
485 | | * |
486 | | *------------------------------------------------------------------------- |
487 | | */ |
488 | | int |
489 | | H5Iinc_type_ref(H5I_type_t type) |
490 | 0 | { |
491 | 0 | int ret_value = -1; /* Return value */ |
492 | |
|
493 | 0 | FUNC_ENTER_API((-1)) |
494 | | |
495 | | /* Check arguments */ |
496 | 0 | if (type <= 0 || (int)type >= H5I_next_type_g) |
497 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID type"); |
498 | 0 | if (H5I_IS_LIB_TYPE(type)) |
499 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, (-1), "cannot call public function on library type"); |
500 | | |
501 | | /* Do actual increment operation */ |
502 | 0 | if ((ret_value = H5I__inc_type_ref(type)) < 0) |
503 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTINC, (-1), "can't increment ID type ref count"); |
504 | | |
505 | 0 | done: |
506 | 0 | FUNC_LEAVE_API(ret_value) |
507 | 0 | } /* end H5Iinc_ref() */ |
508 | | |
509 | | /*------------------------------------------------------------------------- |
510 | | * Function: H5Idec_type_ref |
511 | | * |
512 | | * Purpose: Decrements the reference count on an entire type of IDs. |
513 | | * If the type reference count becomes zero then the type is |
514 | | * destroyed along with all IDs in that type regardless of |
515 | | * their reference counts. Destroying IDs involves calling |
516 | | * the free-func for each ID's object and then adding the ID |
517 | | * struct to the ID free list. Public interface to |
518 | | * H5I_dec_type_ref. |
519 | | * Returns the number of references to the type on success; a |
520 | | * return value of 0 means that the type will have to be |
521 | | * re-initialized before it can be used again (and should probably |
522 | | * be set to H5I_UNINIT). |
523 | | * |
524 | | * NOTE: Using an error type to also represent a count is semantially |
525 | | * incorrect. We should consider fixing this in a future major |
526 | | * release (DER). |
527 | | * |
528 | | * Return: Success: Number of references to type |
529 | | * Failure: -1 |
530 | | * |
531 | | *------------------------------------------------------------------------- |
532 | | */ |
533 | | herr_t |
534 | | H5Idec_type_ref(H5I_type_t type) |
535 | 0 | { |
536 | 0 | herr_t ret_value = 0; /* Return value */ |
537 | |
|
538 | 0 | FUNC_ENTER_API((-1)) |
539 | |
|
540 | 0 | if (H5I_IS_LIB_TYPE(type)) |
541 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, (-1), "cannot call public function on library type"); |
542 | | |
543 | 0 | ret_value = H5I_dec_type_ref(type); |
544 | |
|
545 | 0 | done: |
546 | 0 | FUNC_LEAVE_API(ret_value) |
547 | 0 | } /* end H5Idec_type_ref() */ |
548 | | |
549 | | /*------------------------------------------------------------------------- |
550 | | * Function: H5Iget_type_ref |
551 | | * |
552 | | * Purpose: Retrieves the number of references outstanding for a type. |
553 | | * |
554 | | * Return: Success: Reference count |
555 | | * Failure: -1 |
556 | | * |
557 | | *------------------------------------------------------------------------- |
558 | | */ |
559 | | int |
560 | | H5Iget_type_ref(H5I_type_t type) |
561 | 0 | { |
562 | 0 | int ret_value = -1; /* Return value */ |
563 | |
|
564 | 0 | FUNC_ENTER_API((-1)) |
565 | | |
566 | | /* Check arguments */ |
567 | 0 | if (type <= 0 || (int)type >= H5I_next_type_g) |
568 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID type"); |
569 | 0 | if (H5I_IS_LIB_TYPE(type)) |
570 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, (-1), "cannot call public function on library type"); |
571 | | |
572 | | /* Do actual retrieve operation */ |
573 | 0 | if ((ret_value = H5I__get_type_ref(type)) < 0) |
574 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't get ID type ref count"); |
575 | | |
576 | 0 | done: |
577 | 0 | FUNC_LEAVE_API(ret_value) |
578 | 0 | } /* end H5Iget_ref() */ |
579 | | |
580 | | /*------------------------------------------------------------------------- |
581 | | * Function: H5Iis_valid |
582 | | * |
583 | | * Purpose: Check if the given id is valid. An id is valid if it is in |
584 | | * use and has an application reference count of at least 1. |
585 | | * |
586 | | * Return: true/false/FAIL |
587 | | * |
588 | | *------------------------------------------------------------------------- |
589 | | */ |
590 | | htri_t |
591 | | H5Iis_valid(hid_t id) |
592 | 0 | { |
593 | 0 | H5I_id_info_t *info = NULL; /* Pointer to the ID info */ |
594 | 0 | htri_t ret_value = true; /* Return value */ |
595 | |
|
596 | 0 | FUNC_ENTER_API(FAIL) |
597 | | |
598 | | /* Find the ID */ |
599 | 0 | if (NULL == (info = H5I__find_id(id))) |
600 | 0 | ret_value = false; |
601 | 0 | else if (!info->app_count) /* Check if the found id is an internal id */ |
602 | 0 | ret_value = false; |
603 | |
|
604 | 0 | done: |
605 | 0 | FUNC_LEAVE_API(ret_value) |
606 | 0 | } /* end H5Iis_valid() */ |
607 | | |
608 | | /*------------------------------------------------------------------------- |
609 | | * Function: H5I__search_cb |
610 | | * |
611 | | * Purpose: Callback routine for H5Isearch, when it calls H5I_iterate. |
612 | | * Calls "user" callback search function, and then sets return |
613 | | * value, based on the result of that callback. |
614 | | * |
615 | | * Return: Success: H5_ITER_CONT (0) or H5_ITER_STOP (1) |
616 | | * Failure: H5_ITER_ERROR (-1) |
617 | | * |
618 | | *------------------------------------------------------------------------- |
619 | | */ |
620 | | static int |
621 | | H5I__search_cb(void *obj, hid_t id, void *_udata) |
622 | 0 | { |
623 | 0 | H5I_search_ud_t *udata = (H5I_search_ud_t *)_udata; /* User data for callback */ |
624 | 0 | herr_t cb_ret_val = FAIL; /* User callback return value */ |
625 | 0 | int ret_value = H5_ITER_ERROR; /* Callback return value */ |
626 | |
|
627 | 0 | FUNC_ENTER_PACKAGE_NOERR |
628 | | |
629 | | /* Prepare & restore library for user callback */ |
630 | 0 | H5_BEFORE_USER_CB_NOERR(H5_ITER_ERROR) |
631 | 0 | { |
632 | 0 | cb_ret_val = (*udata->app_cb)(obj, id, udata->app_key); |
633 | 0 | } |
634 | 0 | H5_AFTER_USER_CB_NOERR(H5_ITER_ERROR) |
635 | | |
636 | | /* Set the return value based on the callback's return value */ |
637 | 0 | if (cb_ret_val > 0) { |
638 | 0 | ret_value = H5_ITER_STOP; /* terminate iteration early */ |
639 | 0 | udata->ret_obj = obj; /* also set out parameter */ |
640 | 0 | } |
641 | 0 | else if (cb_ret_val < 0) |
642 | 0 | ret_value = H5_ITER_ERROR; /* indicate failure (which terminates iteration) */ |
643 | |
|
644 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
645 | 0 | } /* end H5I__search_cb() */ |
646 | | |
647 | | /*------------------------------------------------------------------------- |
648 | | * Function: H5Isearch |
649 | | * |
650 | | * Purpose: Apply function FUNC to each member of type TYPE and return a |
651 | | * pointer to the first object for which FUNC returns non-zero. |
652 | | * The FUNC should take a pointer to the object and the KEY as |
653 | | * arguments and return non-zero to terminate the search (zero |
654 | | * to continue). Public interface to H5I_search. |
655 | | * |
656 | | * Limitation: Currently there is no way to start searching from where a |
657 | | * previous search left off. |
658 | | * |
659 | | * Return: Success: The first object in the type for which FUNC |
660 | | * returns non-zero. NULL if FUNC returned zero |
661 | | * for every object in the type. |
662 | | * |
663 | | * Failure: NULL |
664 | | * |
665 | | *------------------------------------------------------------------------- |
666 | | */ |
667 | | void * |
668 | | H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) |
669 | 0 | { |
670 | 0 | H5I_search_ud_t udata; /* Context for iteration */ |
671 | 0 | void *ret_value = NULL; /* Return value */ |
672 | |
|
673 | 0 | FUNC_ENTER_API(NULL) |
674 | | |
675 | | /* Check arguments */ |
676 | 0 | if (H5I_IS_LIB_TYPE(type)) |
677 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "cannot call public function on library type"); |
678 | | |
679 | | /* Set up udata struct */ |
680 | 0 | udata.app_cb = func; |
681 | 0 | udata.app_key = key; |
682 | 0 | udata.ret_obj = NULL; |
683 | | |
684 | | /* Note that H5I_iterate returns an error code. We ignore it |
685 | | * here, as we can't do anything with it without revising the API. |
686 | | */ |
687 | 0 | (void)H5I_iterate(type, H5I__search_cb, &udata, true); |
688 | | |
689 | | /* Set return value */ |
690 | 0 | ret_value = udata.ret_obj; |
691 | |
|
692 | 0 | done: |
693 | 0 | FUNC_LEAVE_API(ret_value) |
694 | 0 | } /* end H5Isearch() */ |
695 | | |
696 | | /*------------------------------------------------------------------------- |
697 | | * Function: H5I__iterate_pub_cb |
698 | | * |
699 | | * Purpose: Callback routine for H5Iiterate, when it calls |
700 | | * H5I_iterate. Calls "user" callback search function, and |
701 | | * then sets return value, based on the result of that |
702 | | * callback. |
703 | | * |
704 | | * Return: Success: H5_ITER_CONT (0) or H5_ITER_STOP (1) |
705 | | * Failure: H5_ITER_ERROR (-1) |
706 | | * |
707 | | *------------------------------------------------------------------------- |
708 | | */ |
709 | | static int |
710 | | H5I__iterate_pub_cb(void H5_ATTR_UNUSED *obj, hid_t id, void *_udata) |
711 | 0 | { |
712 | 0 | H5I_iterate_pub_ud_t *udata = (H5I_iterate_pub_ud_t *)_udata; /* User data for callback */ |
713 | 0 | herr_t cb_ret_val = FAIL; /* User callback return value */ |
714 | 0 | int ret_value = H5_ITER_ERROR; /* Callback return value */ |
715 | |
|
716 | 0 | FUNC_ENTER_PACKAGE_NOERR |
717 | | |
718 | | /* Prepare & restore library for user callback */ |
719 | 0 | H5_BEFORE_USER_CB_NOERR(H5_ITER_ERROR) |
720 | 0 | { |
721 | | /* Invoke the callback */ |
722 | 0 | cb_ret_val = (*udata->op)(id, udata->op_data); |
723 | 0 | } |
724 | 0 | H5_AFTER_USER_CB_NOERR(H5_ITER_ERROR) |
725 | | |
726 | | /* Set the return value based on the callback's return value */ |
727 | 0 | if (cb_ret_val > 0) |
728 | 0 | ret_value = H5_ITER_STOP; /* terminate iteration early */ |
729 | 0 | else if (cb_ret_val < 0) |
730 | 0 | ret_value = H5_ITER_ERROR; /* indicate failure (which terminates iteration) */ |
731 | 0 | else |
732 | 0 | ret_value = H5_ITER_CONT; /* continue iteration */ |
733 | |
|
734 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
735 | 0 | } /* end H5I__iterate_pub_cb() */ |
736 | | |
737 | | /*------------------------------------------------------------------------- |
738 | | * Function: H5Iiterate |
739 | | * |
740 | | * Purpose: Call the callback function op for each member of the id |
741 | | * type type. op takes as parameters the id and a |
742 | | * passthrough of op_data, and returns an herr_t. A positive |
743 | | * return from op will cause the iteration to stop and |
744 | | * H5Iiterate will return the value returned by op. A |
745 | | * negative return from op will cause the iteration to stop |
746 | | * and H5Iiterate will return failure. A zero return from op |
747 | | * will allow iteration to continue, as long as there are |
748 | | * other ids remaining in type. |
749 | | * |
750 | | * Limitation: Currently there is no way to start searching from where a |
751 | | * previous search left off. |
752 | | * |
753 | | * Return: The last value returned by op |
754 | | * |
755 | | *------------------------------------------------------------------------- |
756 | | */ |
757 | | herr_t |
758 | | H5Iiterate(H5I_type_t type, H5I_iterate_func_t op, void *op_data) |
759 | 0 | { |
760 | 0 | H5I_iterate_pub_ud_t int_udata; /* Internal user data */ |
761 | 0 | herr_t ret_value = FAIL; /* Return value */ |
762 | |
|
763 | 0 | FUNC_ENTER_API(FAIL) |
764 | | |
765 | | /* Set up udata struct */ |
766 | 0 | int_udata.op = op; |
767 | 0 | int_udata.op_data = op_data; |
768 | | |
769 | | /* Note that H5I_iterate returns an error code. We ignore it |
770 | | * here, as we can't do anything with it without revising the API. |
771 | | */ |
772 | 0 | if ((ret_value = H5I_iterate(type, H5I__iterate_pub_cb, &int_udata, true)) < 0) |
773 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADITER, FAIL, "can't iterate over ids"); |
774 | | |
775 | 0 | done: |
776 | 0 | FUNC_LEAVE_API(ret_value) |
777 | 0 | } /* end H5Iiterate() */ |
778 | | |
779 | | /*------------------------------------------------------------------------- |
780 | | * Function: H5Iget_file_id |
781 | | * |
782 | | * Purpose: Obtains the file ID given an object ID. The user has to |
783 | | * close this ID. |
784 | | * |
785 | | * Return: Success: The file ID associated with the object |
786 | | * |
787 | | * Failure: H5I_INVALID_HID |
788 | | * |
789 | | *------------------------------------------------------------------------- |
790 | | */ |
791 | | hid_t |
792 | | H5Iget_file_id(hid_t obj_id) |
793 | 0 | { |
794 | 0 | H5I_type_t type; /* ID type */ |
795 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
796 | |
|
797 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
798 | | |
799 | | /* Get object type */ |
800 | 0 | type = H5I_TYPE(obj_id); |
801 | | |
802 | | /* Call internal function */ |
803 | 0 | if (H5I_FILE == type || H5I_DATATYPE == type || H5I_GROUP == type || H5I_DATASET == type || |
804 | 0 | H5I_ATTR == type) { |
805 | 0 | H5VL_object_t *vol_obj; /* Object of obj_id */ |
806 | | |
807 | | /* Get the VOL object */ |
808 | 0 | if (NULL == (vol_obj = H5VL_vol_object(obj_id))) |
809 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier"); |
810 | | |
811 | | /* Get the file ID */ |
812 | 0 | if ((ret_value = H5F_get_file_id(vol_obj, type, true)) < 0) |
813 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTGET, H5I_INVALID_HID, "can't retrieve file ID"); |
814 | 0 | } |
815 | 0 | else |
816 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_INVALID_HID, "not an ID of a file object"); |
817 | | |
818 | 0 | done: |
819 | 0 | FUNC_LEAVE_API(ret_value) |
820 | 0 | } /* end H5Iget_file_id() */ |
821 | | |
822 | | /*------------------------------------------------------------------------- |
823 | | * Function: H5Iget_name |
824 | | * |
825 | | * Purpose: Gets a name of an object from its ID. |
826 | | * |
827 | | * Description: |
828 | | * When 'name' is non-NULL: |
829 | | * - if 'size' > 0: writes up to 'size' bytes into the buffer |
830 | | * (including null terminator) and returns the actual length |
831 | | * of the name (excluding null terminator). |
832 | | * - if 'size' == 0: treats the call as length query, does not |
833 | | * write anything to the buffer (not even a null terminator), and |
834 | | * returns the actual length of the name (excluding null terminator). |
835 | | * |
836 | | * When 'name' is NULL: does not write anything regardless of 'size' |
837 | | * and returns the actual length of the name (excluding null terminator). |
838 | | * |
839 | | * On error, the buffer is unchanged and the function returns |
840 | | * a negative value. |
841 | | * |
842 | | * Return: Success: The length of the name (excluding null terminator) |
843 | | * Failure: Negative |
844 | | * |
845 | | * Notes: |
846 | | * If a zero is returned for the name's length, then there is no name |
847 | | * associated with the ID. |
848 | | * |
849 | | *------------------------------------------------------------------------- |
850 | | */ |
851 | | ssize_t |
852 | | H5Iget_name(hid_t id, char *name /*out*/, size_t size) |
853 | 0 | { |
854 | 0 | H5VL_object_t *vol_obj = NULL; /* Object stored in ID */ |
855 | 0 | H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ |
856 | 0 | H5VL_loc_params_t loc_params; |
857 | 0 | size_t obj_name_len = 0; /* Length of object's name */ |
858 | 0 | ssize_t ret_value = -1; /* Return value */ |
859 | |
|
860 | 0 | FUNC_ENTER_API((-1)) |
861 | | |
862 | | /* If name size is zero, treat as length query and do not write, even a '\0' */ |
863 | 0 | if (name && size == 0) |
864 | 0 | name = NULL; |
865 | | |
866 | | /* Get the object pointer */ |
867 | 0 | if (NULL == (vol_obj = H5VL_vol_object(id))) |
868 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADTYPE, (-1), "invalid identifier"); |
869 | | |
870 | | /* Set location parameters */ |
871 | 0 | loc_params.type = H5VL_OBJECT_BY_SELF; |
872 | 0 | loc_params.obj_type = H5I_get_type(id); |
873 | | |
874 | | /* Set up VOL callback arguments */ |
875 | 0 | vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; |
876 | 0 | vol_cb_args.args.get_name.buf_size = size; |
877 | 0 | vol_cb_args.args.get_name.buf = name; |
878 | 0 | vol_cb_args.args.get_name.name_len = &obj_name_len; |
879 | | |
880 | | /* Retrieve object's name */ |
881 | 0 | if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
882 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object name"); |
883 | | |
884 | | /* Set return value */ |
885 | 0 | ret_value = (ssize_t)obj_name_len; |
886 | |
|
887 | 0 | done: |
888 | | FUNC_LEAVE_API(ret_value) |
889 | 0 | } /* end H5Iget_name() */ |