1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://www.hdfgroup.org/licenses. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /****************/
15 /* Module Setup */
16 /****************/
17
18 #include "H5Mmodule.h" /* This source code file is part of the H5M module */
19
20 /***********/
21 /* Headers */
22 /***********/
23 #include "H5private.h" /* Generic Functions */
24 #include "H5CXprivate.h" /* API Contexts */
25 #include "H5Mpkg.h" /* Maps */
26 #include "H5Eprivate.h" /* Error handling */
27 #include "H5Iprivate.h" /* IDs */
28 #include "H5VLprivate.h" /* Virtual Object Layer */
29
30 /****************/
31 /* Local Macros */
32 /****************/
33
34 /******************/
35 /* Local Typedefs */
36 /******************/
37
38 /********************/
39 /* Local Prototypes */
40 /********************/
41 static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj);
42
43 /*********************/
44 /* Package Variables */
45 /*********************/
46
47 /* Package initialization variable */
48 hbool_t H5_PKG_INIT_VAR = FALSE;
49
50 /*****************************/
51 /* Library Private Variables */
52 /*****************************/
53
54 /*******************/
55 /* Local Variables */
56 /*******************/
57
58 /* Map ID class */
59 static const H5I_class_t H5I_MAP_CLS[1] = {{
60 H5I_MAP, /* ID class value */
61 0, /* Class flags */
62 0, /* # of reserved IDs for class */
63 (H5I_free_t)H5M__close_cb /* Callback routine for closing objects of this class */
64 }};
65
66 /* Flag indicating "top" of interface has been initialized */
67 static hbool_t H5M_top_package_initialize_s = FALSE;
68
69 /*-------------------------------------------------------------------------
70 * Function: H5M_init
71 *
72 * Purpose: Initialize the interface from some other layer.
73 *
74 * Return: Success: non-negative
75 *
76 * Failure: negative
77 *-------------------------------------------------------------------------
78 */
79 herr_t
H5M_init(void)80 H5M_init(void)
81 {
82 herr_t ret_value = SUCCEED; /* Return value */
83
84 FUNC_ENTER_NOAPI(FAIL)
85 /* FUNC_ENTER() does all the work */
86
87 done:
88 FUNC_LEAVE_NOAPI(ret_value)
89 } /* end H5M_init() */
90
91 /*-------------------------------------------------------------------------
92 NAME
93 H5M__init_package -- Initialize interface-specific information
94 USAGE
95 herr_t H5M__init_package()
96
97 RETURNS
98 Non-negative on success/Negative on failure
99 DESCRIPTION
100 Initializes any interface-specific data or routines.
101 ---------------------------------------------------------------------------
102 */
103 herr_t
H5M__init_package(void)104 H5M__init_package(void)
105 {
106 herr_t ret_value = SUCCEED; /* Return value */
107
108 FUNC_ENTER_PACKAGE
109
110 /* Initialize the atom group for the map IDs */
111 if (H5I_register_type(H5I_MAP_CLS) < 0)
112 HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, FAIL, "unable to initialize interface")
113
114 /* Mark "top" of interface as initialized, too */
115 H5M_top_package_initialize_s = TRUE;
116
117 done:
118 FUNC_LEAVE_NOAPI(ret_value)
119 } /* end H5M__init_package() */
120
121 /*-------------------------------------------------------------------------
122 * Function: H5M_top_term_package
123 *
124 * Purpose: Close the "top" of the interface, releasing IDs, etc.
125 *
126 * Return: Success: Positive if anything was done that might
127 * affect other interfaces; zero otherwise.
128 * Failure: Negative.
129 *-------------------------------------------------------------------------
130 */
131 int
H5M_top_term_package(void)132 H5M_top_term_package(void)
133 {
134 int n = 0;
135
136 FUNC_ENTER_NOAPI_NOINIT_NOERR
137
138 if (H5M_top_package_initialize_s) {
139 if (H5I_nmembers(H5I_MAP) > 0) {
140 (void)H5I_clear_type(H5I_MAP, FALSE, FALSE);
141 n++; /*H5I*/
142 } /* end if */
143
144 /* Mark closed */
145 if (0 == n)
146 H5M_top_package_initialize_s = FALSE;
147 } /* end if */
148
149 FUNC_LEAVE_NOAPI(n)
150 } /* end H5M_top_term_package() */
151
152 /*-------------------------------------------------------------------------
153 * Function: H5M_term_package
154 *
155 * Purpose: Terminate this interface.
156 *
157 * Note: Finishes shutting down the interface, after
158 * H5M_top_term_package() is called
159 *
160 * Return: Success: Positive if anything was done that might
161 * affect other interfaces; zero otherwise.
162 * Failure: Negative.
163 *-------------------------------------------------------------------------
164 */
165 int
H5M_term_package(void)166 H5M_term_package(void)
167 {
168 int n = 0;
169
170 FUNC_ENTER_NOAPI_NOINIT_NOERR
171
172 if (H5_PKG_INIT_VAR) {
173 /* Sanity checks */
174 HDassert(0 == H5I_nmembers(H5I_MAP));
175 HDassert(FALSE == H5M_top_package_initialize_s);
176
177 /* Destroy the dataset object id group */
178 n += (H5I_dec_type_ref(H5I_MAP) > 0);
179
180 /* Mark closed */
181 if (0 == n)
182 H5_PKG_INIT_VAR = FALSE;
183 } /* end if */
184
185 FUNC_LEAVE_NOAPI(n)
186 } /* end H5M_term_package() */
187
188 /*-------------------------------------------------------------------------
189 * Function: H5M__close_cb
190 *
191 * Purpose: Called when the ref count reaches zero on the map's ID
192 *
193 * Return: SUCCEED/FAIL
194 *
195 *-------------------------------------------------------------------------
196 */
197 static herr_t
H5M__close_cb(H5VL_object_t * map_vol_obj)198 H5M__close_cb(H5VL_object_t *map_vol_obj)
199 {
200 herr_t ret_value = SUCCEED; /* Return value */
201
202 FUNC_ENTER_STATIC
203
204 /* Sanity check */
205 HDassert(map_vol_obj);
206
207 /* Close the map */
208 if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
209 HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map");
210
211 /* Free the VOL object */
212 if (H5VL_free_object(map_vol_obj) < 0)
213 HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "unable to free VOL object");
214
215 done:
216 FUNC_LEAVE_NOAPI(ret_value)
217 } /* end H5M__close_cb() */
218
219 #ifdef H5_HAVE_MAP_API
220
221 /*-------------------------------------------------------------------------
222 * Function: H5Mcreate
223 *
224 * Purpose: Creates a new map object for storing key-value pairs. The
225 * in-file datatype for keys is defined by KEY_TYPE_ID and
226 * the in-file datatype for values is defined by VAL_TYPE_ID.
227 * LOC_ID specifies the location to create the map object and
228 * NAME specifies the name of the link to the object
229 * (relative to LOC_ID). Other options can be specified
230 * through the property lists LCPL_ID, MCPL_ID, and MAPL_ID.
231 *
232 * Return: Success: The object ID of the new map.
233 *
234 * Failure: H5I_INVALID_HID
235 *
236 *-------------------------------------------------------------------------
237 */
238 hid_t
H5Mcreate(hid_t loc_id,const char * name,hid_t key_type_id,hid_t val_type_id,hid_t lcpl_id,hid_t mcpl_id,hid_t mapl_id)239 H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id,
240 hid_t mapl_id)
241 {
242 void * map = NULL; /* New map's info */
243 H5VL_object_t * vol_obj = NULL; /* object of loc_id */
244 H5VL_loc_params_t loc_params;
245 hid_t ret_value = H5I_INVALID_HID; /* Return value */
246
247 FUNC_ENTER_API(H5I_INVALID_HID)
248 H5TRACE7("i", "i*siiiii", loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id);
249
250 /* Check arguments */
251 if (!name)
252 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL")
253 if (!*name)
254 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
255
256 /* Get link creation property list */
257 if (H5P_DEFAULT == lcpl_id)
258 lcpl_id = H5P_LINK_CREATE_DEFAULT;
259 else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
260 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "lcpl_id is not a link creation property list")
261
262 /* Get map creation property list */
263 if (H5P_DEFAULT == mcpl_id)
264 mcpl_id = H5P_MAP_CREATE_DEFAULT;
265 else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
266 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID")
267
268 /* Verify access property list and set up collective metadata if appropriate */
269 if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, TRUE) < 0)
270 HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
271
272 /* Get the location object */
273 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
274 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
275
276 /* Set location parameters */
277 loc_params.type = H5VL_OBJECT_BY_SELF;
278 loc_params.obj_type = H5I_get_type(loc_id);
279
280 /* Create the map */
281 if (H5VL_optional(vol_obj, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, name,
282 lcpl_id, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0)
283 HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map")
284
285 /* Get an atom for the map */
286 if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0)
287 HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize map handle")
288
289 done:
290 /* Cleanup on failure */
291 if (H5I_INVALID_HID == ret_value)
292 if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
293 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")
294
295 FUNC_LEAVE_API(ret_value)
296 } /* end H5Mcreate() */
297
298 /*-------------------------------------------------------------------------
299 * Function: H5Mcreate_anon
300 *
301 * Purpose: Creates a new map object for storing key-value pairs. The
302 * in-file datatype for keys is defined by KEY_TYPE_ID and
303 * the in-file datatype for values is defined by VAL_TYPE_ID.
304 * LOC_ID specifies the file to create the map object, but no
305 * link to the object is created. Other options can be
306 * specified through the property lists LCPL_ID, MCPL_ID, and
307 * MAPL_ID.
308 *
309 * The resulting ID should be linked into the file with
310 * H5Olink or it will be deleted when closed.
311 *
312 * Return: Success: The object ID of the new map. The map should
313 * be linked into the group hierarchy before being closed or
314 * it will be deleted. The dataset should be
315 * closed when the caller is no longer interested
316 * in it.
317 *
318 * Failure: H5I_INVALID_HID
319 *
320 *-------------------------------------------------------------------------
321 */
322 hid_t
H5Mcreate_anon(hid_t loc_id,hid_t key_type_id,hid_t val_type_id,hid_t mcpl_id,hid_t mapl_id)323 H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id)
324 {
325 void * map = NULL; /* map object from VOL connector */
326 H5VL_object_t * vol_obj = NULL; /* object of loc_id */
327 H5VL_loc_params_t loc_params;
328 hid_t ret_value = H5I_INVALID_HID; /* Return value */
329
330 FUNC_ENTER_API(H5I_INVALID_HID)
331 H5TRACE5("i", "iiiii", loc_id, key_type_id, val_type_id, mcpl_id, mapl_id);
332
333 /* Check arguments */
334 if (H5P_DEFAULT == mcpl_id)
335 mcpl_id = H5P_MAP_CREATE_DEFAULT;
336 else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
337 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not map create property list ID")
338
339 /* Verify access property list and set up collective metadata if appropriate */
340 if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, TRUE) < 0)
341 HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
342
343 /* get the location object */
344 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
345 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
346
347 /* Set location parameters */
348 loc_params.type = H5VL_OBJECT_BY_SELF;
349 loc_params.obj_type = H5I_get_type(loc_id);
350
351 /* Create the map */
352 if (H5VL_optional(vol_obj, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, NULL,
353 H5P_LINK_CREATE_DEFAULT, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0)
354 HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map")
355
356 /* Get an atom for the map */
357 if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0)
358 HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map")
359
360 done:
361 /* Cleanup on failure */
362 if (H5I_INVALID_HID == ret_value)
363 if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
364 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")
365
366 FUNC_LEAVE_API(ret_value)
367 } /* end H5Mcreate_anon() */
368
369 /*------------------------------------------------------------------------
370 * Function: H5Mopen
371 *
372 * Purpose: Finds a map named NAME at LOC_ID, opens it, and returns
373 * its ID. The map should be close when the caller is no
374 * longer interested in it.
375 *
376 * Takes a map access property list
377 *
378 * Return: Success: Object ID of the map
379 *
380 * Failure: H5I_INVALID_HID
381 *
382 *-------------------------------------------------------------------------
383 */
384 hid_t
H5Mopen(hid_t loc_id,const char * name,hid_t mapl_id)385 H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id)
386 {
387 void * map = NULL; /* map object from VOL connector */
388 H5VL_object_t * vol_obj = NULL; /* object of loc_id */
389 H5VL_loc_params_t loc_params;
390 hid_t ret_value = H5I_INVALID_HID; /* Return value */
391
392 FUNC_ENTER_API(H5I_INVALID_HID)
393 H5TRACE3("i", "i*si", loc_id, name, mapl_id);
394
395 /* Check args */
396 if (!name)
397 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL")
398 if (!*name)
399 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
400
401 /* Verify access property list and set up collective metadata if appropriate */
402 if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, FALSE) < 0)
403 HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
404
405 /* get the location object */
406 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
407 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
408
409 /* Set the location parameters */
410 loc_params.type = H5VL_OBJECT_BY_SELF;
411 loc_params.obj_type = H5I_get_type(loc_id);
412
413 /* Open the map */
414 if (H5VL_optional(vol_obj, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, name,
415 mapl_id, &map) < 0)
416 HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map")
417
418 /* Register an atom for the map */
419 if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0)
420 HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register map atom")
421
422 done:
423 /* Cleanup on failure */
424 if (H5I_INVALID_HID == ret_value)
425 if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
426 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")
427
428 FUNC_LEAVE_API(ret_value)
429 } /* end H5Mopen() */
430
431 /*-------------------------------------------------------------------------
432 * Function: H5Mclose
433 *
434 * Purpose: Closes access to a map and releases resources used by it.
435 * It is illegal to subsequently use that same map ID in
436 * calls to other map functions.
437 *
438 * Return: SUCCEED/FAIL
439 *
440 *-------------------------------------------------------------------------
441 */
442 herr_t
H5Mclose(hid_t map_id)443 H5Mclose(hid_t map_id)
444 {
445 herr_t ret_value = SUCCEED; /* Return value */
446
447 FUNC_ENTER_API(FAIL)
448 H5TRACE1("e", "i", map_id);
449
450 /* Check args */
451 if (H5I_MAP != H5I_get_type(map_id))
452 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID")
453
454 /* Decrement the counter on the map. It will be freed if the count
455 * reaches zero.
456 */
457 if (H5I_dec_app_ref_always_close(map_id) < 0)
458 HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on map ID")
459
460 done:
461 FUNC_LEAVE_API(ret_value)
462 } /* end H5Mclose() */
463
464 /*-------------------------------------------------------------------------
465 * Function: H5Mget_key_type
466 *
467 * Purpose: Returns a copy of the key datatype for a map.
468 *
469 * Return: Success: ID for a copy of the datatype. The data
470 * type should be released by calling
471 * H5Tclose().
472 *
473 * Failure: H5I_INVALID_HID
474 *
475 *-------------------------------------------------------------------------
476 */
477 hid_t
H5Mget_key_type(hid_t map_id)478 H5Mget_key_type(hid_t map_id)
479 {
480 H5VL_object_t *vol_obj; /* Map structure */
481 hid_t ret_value = H5I_INVALID_HID; /* Return value */
482
483 FUNC_ENTER_API(H5I_INVALID_HID)
484 H5TRACE1("i", "i", map_id);
485
486 /* Check args */
487 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
488 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")
489
490 /* get the datatype */
491 if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_KEY_TYPE,
492 &ret_value) < 0)
493 HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype")
494
495 done:
496 FUNC_LEAVE_API(ret_value)
497 } /* end H5Mget_key_type() */
498
499 /*-------------------------------------------------------------------------
500 * Function: H5Mget_val_type
501 *
502 * Purpose: Returns a copy of the value datatype for a map.
503 *
504 * Return: Success: ID for a copy of the datatype. The data
505 * type should be released by calling
506 * H5Tclose().
507 *
508 * Failure: H5I_INVALID_HID
509 *
510 *-------------------------------------------------------------------------
511 */
512 hid_t
H5Mget_val_type(hid_t map_id)513 H5Mget_val_type(hid_t map_id)
514 {
515 H5VL_object_t *vol_obj; /* Map structure */
516 hid_t ret_value = H5I_INVALID_HID; /* Return value */
517
518 FUNC_ENTER_API(H5I_INVALID_HID)
519 H5TRACE1("i", "i", map_id);
520
521 /* Check args */
522 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
523 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")
524
525 /* get the datatype */
526 if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_VAL_TYPE,
527 &ret_value) < 0)
528 HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype")
529
530 done:
531 FUNC_LEAVE_API(ret_value)
532 } /* end H5Mget_val_type() */
533
534 /*-------------------------------------------------------------------------
535 * Function: H5Mget_create_plist
536 *
537 * Purpose: Returns a copy of the map creation property list.
538 *
539 * Return: Success: ID for a copy of the map creation
540 * property list. The template should be
541 * released by calling H5P_close().
542 *
543 * Failure: H5I_INVALID_HID
544 *
545 *-------------------------------------------------------------------------
546 */
547 hid_t
H5Mget_create_plist(hid_t map_id)548 H5Mget_create_plist(hid_t map_id)
549 {
550 H5VL_object_t *vol_obj; /* Map structure */
551 hid_t ret_value = H5I_INVALID_HID; /* Return value */
552
553 FUNC_ENTER_API(H5I_INVALID_HID)
554 H5TRACE1("i", "i", map_id);
555
556 /* Check args */
557 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
558 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")
559
560 /* Get the map creation property list */
561 if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MCPL,
562 &ret_value) < 0)
563 HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map creation properties")
564
565 done:
566 FUNC_LEAVE_API(ret_value)
567 } /* end H5Mget_create_plist() */
568
569 /*-------------------------------------------------------------------------
570 * Function: H5Mget_access_plist
571 *
572 * Purpose: Returns a copy of the map access property list.
573 *
574 * Description: H5Mget_access_plist returns the map access property
575 * list identifier of the specified map.
576 *
577 * Return: Success: ID for a copy of the map access
578 * property list. The template should be
579 * released by calling H5Pclose().
580 *
581 * Failure: H5I_INVALID_HID
582 *
583 *-------------------------------------------------------------------------
584 */
585 hid_t
H5Mget_access_plist(hid_t map_id)586 H5Mget_access_plist(hid_t map_id)
587 {
588 H5VL_object_t *vol_obj; /* Map structure */
589 hid_t ret_value = H5I_INVALID_HID; /* Return value */
590
591 FUNC_ENTER_API(H5I_INVALID_HID)
592 H5TRACE1("i", "i", map_id);
593
594 /* Check args */
595 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
596 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")
597
598 /* Get the map access property list */
599 if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MAPL,
600 &ret_value) < 0)
601 HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties")
602
603 done:
604 FUNC_LEAVE_API(ret_value)
605 } /* end H5Mget_access_plist() */
606
607 /*-------------------------------------------------------------------------
608 * Function: H5Mget_count
609 *
610 * Purpose: Returns the number of key-value pairs stored in the map.
611 *
612 * Description: H5Mget_count returns the number of key-value pairs stored
613 * in the specified map.
614 *
615 * Return: SUCCEED/FAIL
616 *
617 *-------------------------------------------------------------------------
618 */
619 herr_t
H5Mget_count(hid_t map_id,hsize_t * count,hid_t dxpl_id)620 H5Mget_count(hid_t map_id, hsize_t *count, hid_t dxpl_id)
621 {
622 H5VL_object_t *vol_obj; /* Map structure */
623 herr_t ret_value = SUCCEED; /* Return value */
624
625 FUNC_ENTER_API(H5I_INVALID_HID)
626 H5TRACE3("e", "i*hi", map_id, count, dxpl_id);
627
628 /* Check args */
629 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
630 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier")
631
632 /* Get the default dataset transfer property list if the user didn't provide one */
633 if (H5P_DEFAULT == dxpl_id)
634 dxpl_id = H5P_DATASET_XFER_DEFAULT;
635 else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
636 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
637
638 /* Set DXPL for operation */
639 H5CX_set_dxpl(dxpl_id);
640
641 /* Get the number of key-value pairs stored in the map */
642 if (H5VL_optional(vol_obj, H5VL_MAP_GET, dxpl_id, H5_REQUEST_NULL, H5VL_MAP_GET_COUNT, count) < 0)
643 HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties")
644
645 done:
646 FUNC_LEAVE_API(ret_value)
647 } /* end H5Mget_count() */
648
649 /*-------------------------------------------------------------------------
650 * Function: H5Mput
651 *
652 * Purpose: H5Mput adds a key-value pair to the Map specified by
653 * MAP_ID, or updates the value for the specified key if one
654 * was set previously. KEY_MEM_TYPE_ID and VAL_MEM_TYPE_ID
655 * specify the datatypes for the provided KEY and VALUE
656 * buffers, and if different from those used to create the
657 * map object, the key and value will be internally converted
658 * to the datatypes for the map object. Any further options
659 * can be specified through the property list DXPL_ID.
660 *
661 * Return: SUCCEED/FAIL
662 *
663 *-------------------------------------------------------------------------
664 */
665 herr_t
H5Mput(hid_t map_id,hid_t key_mem_type_id,const void * key,hid_t val_mem_type_id,const void * value,hid_t dxpl_id)666 H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value,
667 hid_t dxpl_id)
668 {
669 H5VL_object_t *vol_obj = NULL;
670 herr_t ret_value = SUCCEED; /* Return value */
671
672 FUNC_ENTER_API(FAIL)
673 H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id);
674
675 /* Check arguments */
676 if (key_mem_type_id < 0)
677 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
678 if (val_mem_type_id < 0)
679 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID")
680
681 /* Get map pointer */
682 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
683 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
684
685 /* Get the default dataset transfer property list if the user didn't provide one */
686 if (H5P_DEFAULT == dxpl_id)
687 dxpl_id = H5P_DATASET_XFER_DEFAULT;
688 else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
689 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
690
691 /* Set DXPL for operation */
692 H5CX_set_dxpl(dxpl_id);
693
694 /* Set the key/value pair */
695 if (H5VL_optional(vol_obj, H5VL_MAP_PUT, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key, val_mem_type_id,
696 value) < 0)
697 HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair")
698
699 done:
700 FUNC_LEAVE_API(ret_value)
701 } /* end H5Mput() */
702
703 /*-------------------------------------------------------------------------
704 * Function: H5Mget
705 *
706 * Purpose: H5Mget retrieves, from the Map specified by MAP_ID, the
707 * value associated with the provided key. KEY_MEM_TYPE_ID
708 * and VAL_MEM_TYPE_ID specify the datatypes for the provided
709 * KEY and VALUE buffers. If KEY_MEM_TYPE_ID is different
710 * from that used to create the map object, the key will be
711 * internally converted to the datatype for the map object
712 * for the query, and if VAL_MEM_TYPE_ID is different from
713 * that used to create the map object, the returned value
714 * will be converted to VAL_MEM_TYPE_ID before the function
715 * returns. Any further options can be specified through the
716 * property list DXPL_ID.
717 *
718 * Return: SUCCEED/FAIL
719 *
720 *-------------------------------------------------------------------------
721 */
722 herr_t
H5Mget(hid_t map_id,hid_t key_mem_type_id,const void * key,hid_t val_mem_type_id,void * value,hid_t dxpl_id)723 H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
724 hid_t dxpl_id)
725 {
726 H5VL_object_t *vol_obj = NULL;
727 herr_t ret_value = SUCCEED; /* Return value */
728
729 FUNC_ENTER_API(FAIL)
730 H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id);
731
732 /* Check arguments */
733 if (key_mem_type_id < 0)
734 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
735 if (val_mem_type_id < 0)
736 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID")
737
738 /* Get map pointer */
739 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
740 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
741
742 /* Get the default dataset transfer property list if the user didn't provide one */
743 if (H5P_DEFAULT == dxpl_id)
744 dxpl_id = H5P_DATASET_XFER_DEFAULT;
745 else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
746 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
747
748 /* Set DXPL for operation */
749 H5CX_set_dxpl(dxpl_id);
750
751 /* Get the value for the key */
752 if (H5VL_optional(vol_obj, H5VL_MAP_GET_VAL, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key,
753 val_mem_type_id, value) < 0)
754 HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map")
755
756 done:
757 FUNC_LEAVE_API(ret_value)
758 } /* end H5Mget() */
759
760 /*-------------------------------------------------------------------------
761 * Function: H5Mexists
762 *
763 * Purpose: H5Mexists checks if the provided key is stored in the map
764 * specified by MAP_ID. If KEY_MEM_TYPE_ID is different from
765 * that used to create the map object the key will be
766 * internally converted to the datatype for the map object
767 * for the query.
768 *
769 * Return: SUCCEED/FAIL
770 *
771 *-------------------------------------------------------------------------
772 */
773 herr_t
H5Mexists(hid_t map_id,hid_t key_mem_type_id,const void * key,hbool_t * exists,hid_t dxpl_id)774 H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id)
775 {
776 H5VL_object_t *vol_obj = NULL;
777 herr_t ret_value = SUCCEED; /* Return value */
778
779 FUNC_ENTER_API(FAIL)
780 H5TRACE5("e", "ii*x*bi", map_id, key_mem_type_id, key, exists, dxpl_id);
781
782 /* Check arguments */
783 if (key_mem_type_id < 0)
784 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
785
786 /* Get map pointer */
787 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
788 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
789
790 /* Get the default dataset transfer property list if the user didn't provide one */
791 if (H5P_DEFAULT == dxpl_id)
792 dxpl_id = H5P_DATASET_XFER_DEFAULT;
793 else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
794 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
795
796 /* Set DXPL for operation */
797 H5CX_set_dxpl(dxpl_id);
798
799 /* Check if key exists */
800 if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_EXISTS, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key,
801 exists)) < 0)
802 HGOTO_ERROR(H5E_MAP, H5E_CANTGET, ret_value, "unable to check if key exists")
803
804 done:
805 FUNC_LEAVE_API(ret_value)
806 } /* end H5Mexists() */
807
808 /*-------------------------------------------------------------------------
809 * Function: H5Miterate
810 *
811 * Purpose: H5Miterate iterates over all key-value pairs stored in the
812 * map specified by MAP_ID, making the callback specified by
813 * OP for each. The IDX parameter is an in/out parameter that
814 * may be used to restart a previously interrupted iteration.
815 * At the start of iteration IDX should be set to 0, and to
816 * restart iteration at the same location on a subsequent
817 * call to H5Miterate, IDX should be the same value as
818 * returned by the previous call.
819 *
820 * H5M_iterate_t is defined as:
821 * herr_t (*H5M_iterate_t)(hid_t map_id, const void *key,
822 * void *ctx)
823 *
824 * The KEY parameter is the buffer for the key for this
825 * iteration, converted to the datatype specified by
826 * KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass
827 * through of the value passed to H5Miterate, which can be
828 * used to store application-defined data for iteration. A
829 * negative return value from this function will cause
830 * H5Miterate to issue an error, while a positive return
831 * value will cause H5Miterate to stop iterating and return
832 * this value without issuing an error. A return value of
833 * zero allows iteration to continue.
834 *
835 * Return: Last value returned by op
836 *
837 *-------------------------------------------------------------------------
838 */
839 herr_t
H5Miterate(hid_t map_id,hsize_t * idx,hid_t key_mem_type_id,H5M_iterate_t op,void * op_data,hid_t dxpl_id)840 H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data, hid_t dxpl_id)
841 {
842 H5VL_object_t * vol_obj = NULL;
843 H5VL_loc_params_t loc_params;
844 herr_t ret_value = SUCCEED; /* Return value */
845
846 FUNC_ENTER_API(FAIL)
847 H5TRACE6("e", "i*hix*xi", map_id, idx, key_mem_type_id, op, op_data, dxpl_id);
848
849 /* Check arguments */
850 if (key_mem_type_id < 0)
851 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
852 if (!op)
853 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")
854
855 /* Get map pointer */
856 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
857 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
858
859 /* Get the default dataset transfer property list if the user didn't provide one */
860 if (H5P_DEFAULT == dxpl_id)
861 dxpl_id = H5P_DATASET_XFER_DEFAULT;
862 else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
863 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
864
865 /* Set DXPL for operation */
866 H5CX_set_dxpl(dxpl_id);
867
868 /* Set location struct fields */
869 loc_params.type = H5VL_OBJECT_BY_SELF;
870 loc_params.obj_type = H5I_get_type(map_id);
871
872 /* Iterate over keys */
873 if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params,
874 H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0)
875 HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to iterate over keys")
876
877 done:
878 FUNC_LEAVE_API(ret_value)
879 } /* end H5Miterate() */
880
881 /*-------------------------------------------------------------------------
882 * Function: H5Miterate_by_name
883 *
884 * Purpose: H5Miterate_by_name iterates over all key-value pairs
885 * stored in the map specified by MAP_ID, making the callback
886 * specified by OP for each. The IDX parameter is an in/out
887 * parameter that may be used to restart a previously
888 * interrupted iteration. At the start of iteration IDX
889 * should be set to 0, and to restart iteration at the same
890 * location on a subsequent call to H5Miterate, IDX should be
891 * the same value as returned by the previous call.
892 *
893 * H5M_iterate_t is defined as:
894 * herr_t (*H5M_iterate_t)(hid_t map_id, const void *key,
895 * void *ctx)
896 *
897 * The KEY parameter is the buffer for the key for this
898 * iteration, converted to the datatype specified by
899 * KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass
900 * through of the value passed to H5Miterate, which can be
901 * used to store application-defined data for iteration. A
902 * negative return value from this function will cause
903 * H5Miterate to issue an error, while a positive return
904 * value will cause H5Miterate to stop iterating and return
905 * this value without issuing an error. A return value of
906 * zero allows iteration to continue.
907 *
908 * Return: Last value returned by op
909 *
910 *-------------------------------------------------------------------------
911 */
912 herr_t
H5Miterate_by_name(hid_t loc_id,const char * map_name,hsize_t * idx,hid_t key_mem_type_id,H5M_iterate_t op,void * op_data,hid_t dxpl_id,hid_t lapl_id)913 H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op,
914 void *op_data, hid_t dxpl_id, hid_t lapl_id)
915 {
916 H5VL_object_t * vol_obj = NULL;
917 H5VL_loc_params_t loc_params;
918 herr_t ret_value = SUCCEED; /* Return value */
919
920 FUNC_ENTER_API(FAIL)
921 H5TRACE8("e", "i*s*hix*xii", loc_id, map_name, idx, key_mem_type_id, op, op_data, dxpl_id, lapl_id);
922
923 /* Check arguments */
924 if (!map_name)
925 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be NULL")
926 if (!*map_name)
927 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be an empty string")
928 if (key_mem_type_id < 0)
929 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
930 if (!op)
931 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")
932
933 /* Get the location object */
934 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
935 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
936
937 /* Get the default dataset transfer property list if the user didn't provide one */
938 if (H5P_DEFAULT == dxpl_id)
939 dxpl_id = H5P_DATASET_XFER_DEFAULT;
940 else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
941 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
942
943 /* Set DXPL for operation */
944 H5CX_set_dxpl(dxpl_id);
945
946 /* Set location struct fields */
947 loc_params.type = H5VL_OBJECT_BY_NAME;
948 loc_params.obj_type = H5I_get_type(loc_id);
949 loc_params.loc_data.loc_by_name.name = map_name;
950 loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
951
952 /* Iterate over keys */
953 if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params,
954 H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0)
955 HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to ierate over keys")
956
957 done:
958 FUNC_LEAVE_API(ret_value)
959 } /* end H5Miterate_by_name() */
960
961 /*-------------------------------------------------------------------------
962 * Function: H5Mdelete
963 *
964 * Purpose: H5Mdelete deletes a key-value pair from the Map
965 * specified by MAP_ID. KEY_MEM_TYPE_ID specifies the
966 * datatype for the provided key buffers, and if different
967 * from that used to create the Map object, the key will be
968 * internally converted to the datatype for the map object.
969 * Any further options can be specified through the property
970 * list DXPL_ID.
971 *
972 * Return: SUCCEED/FAIL
973 *
974 *-------------------------------------------------------------------------
975 */
976 herr_t
H5Mdelete(hid_t map_id,hid_t key_mem_type_id,const void * key,hid_t dxpl_id)977 H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id)
978 {
979 H5VL_object_t * vol_obj = NULL;
980 H5VL_loc_params_t loc_params;
981 herr_t ret_value = SUCCEED; /* Return value */
982
983 FUNC_ENTER_API(FAIL)
984 H5TRACE4("e", "ii*xi", map_id, key_mem_type_id, key, dxpl_id);
985
986 /* Check arguments */
987 if (key_mem_type_id < 0)
988 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
989
990 /* Get map pointer */
991 if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
992 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
993
994 /* Get the default dataset transfer property list if the user didn't provide one */
995 if (H5P_DEFAULT == dxpl_id)
996 dxpl_id = H5P_DATASET_XFER_DEFAULT;
997 else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
998 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
999
1000 /* Set DXPL for operation */
1001 H5CX_set_dxpl(dxpl_id);
1002
1003 /* Set location struct fields */
1004 loc_params.type = H5VL_OBJECT_BY_SELF;
1005 loc_params.obj_type = H5I_get_type(map_id);
1006
1007 /* Delete the key/value pair */
1008 if (H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, H5VL_MAP_DELETE,
1009 key_mem_type_id, key) < 0)
1010 HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to delete key/value pair")
1011
1012 done:
1013 FUNC_LEAVE_API(ret_value)
1014 } /* end H5Mdelete() */
1015
1016 #endif /* H5_HAVE_MAP_API */
1017