Line | Count | Source (jump to first uncovered line) |
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 COPYING 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 | | /* Module Setup */ |
15 | | /****************/ |
16 | | |
17 | | #include "H5Mmodule.h" /* This source code file is part of the H5M module */ |
18 | | |
19 | | /***********/ |
20 | | /* Headers */ |
21 | | /***********/ |
22 | | #include "H5private.h" /* Generic Functions */ |
23 | | #include "H5CXprivate.h" /* API Contexts */ |
24 | | #include "H5Mpkg.h" /* Maps */ |
25 | | #include "H5Eprivate.h" /* Error handling */ |
26 | | #include "H5ESprivate.h" /* Event Sets */ |
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, void **request); |
42 | | |
43 | | #ifdef H5_HAVE_MAP_API |
44 | | static hid_t H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, |
45 | | hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, void **token_ptr, |
46 | | H5VL_object_t **_vol_obj_ptr); |
47 | | static hid_t H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr, |
48 | | H5VL_object_t **_vol_obj_ptr); |
49 | | static herr_t H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, |
50 | | const void *value, hid_t dxpl_id, void **token_ptr, |
51 | | H5VL_object_t **_vol_obj_ptr); |
52 | | static herr_t H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, |
53 | | void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); |
54 | | #endif /* H5_HAVE_MAP_API */ |
55 | | |
56 | | /*********************/ |
57 | | /* Package Variables */ |
58 | | /*********************/ |
59 | | |
60 | | /*****************************/ |
61 | | /* Library Private Variables */ |
62 | | /*****************************/ |
63 | | |
64 | | /*******************/ |
65 | | /* Local Variables */ |
66 | | /*******************/ |
67 | | |
68 | | /* Map ID class */ |
69 | | static const H5I_class_t H5I_MAP_CLS[1] = {{ |
70 | | H5I_MAP, /* ID class value */ |
71 | | 0, /* Class flags */ |
72 | | 0, /* # of reserved IDs for class */ |
73 | | (H5I_free_t)H5M__close_cb /* Callback routine for closing objects of this class */ |
74 | | }}; |
75 | | |
76 | | /*------------------------------------------------------------------------- |
77 | | * Function: H5M_init |
78 | | * |
79 | | * Purpose: Initialize the interface from some other layer. |
80 | | * |
81 | | * Return: Success: non-negative |
82 | | * |
83 | | * Failure: negative |
84 | | *------------------------------------------------------------------------- |
85 | | */ |
86 | | herr_t |
87 | | H5M_init(void) |
88 | 1 | { |
89 | 1 | herr_t ret_value = SUCCEED; /* Return value */ |
90 | | |
91 | 1 | FUNC_ENTER_NOAPI(FAIL) |
92 | | |
93 | | /* Initialize the ID group for the map IDs */ |
94 | 1 | if (H5I_register_type(H5I_MAP_CLS) < 0) |
95 | 0 | HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, FAIL, "unable to initialize interface"); |
96 | | |
97 | 1 | done: |
98 | 1 | FUNC_LEAVE_NOAPI(ret_value) |
99 | 1 | } /* end H5M_init() */ |
100 | | |
101 | | /*------------------------------------------------------------------------- |
102 | | * Function: H5M_top_term_package |
103 | | * |
104 | | * Purpose: Close the "top" of the interface, releasing IDs, etc. |
105 | | * |
106 | | * Return: Success: Positive if anything was done that might |
107 | | * affect other interfaces; zero otherwise. |
108 | | * Failure: Negative. |
109 | | *------------------------------------------------------------------------- |
110 | | */ |
111 | | int |
112 | | H5M_top_term_package(void) |
113 | 1 | { |
114 | 1 | int n = 0; |
115 | | |
116 | 1 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
117 | | |
118 | 1 | if (H5I_nmembers(H5I_MAP) > 0) { |
119 | 0 | (void)H5I_clear_type(H5I_MAP, false, false); |
120 | 0 | n++; |
121 | 0 | } |
122 | | |
123 | 1 | FUNC_LEAVE_NOAPI(n) |
124 | 1 | } /* end H5M_top_term_package() */ |
125 | | |
126 | | /*------------------------------------------------------------------------- |
127 | | * Function: H5M_term_package |
128 | | * |
129 | | * Purpose: Terminate this interface. |
130 | | * |
131 | | * Note: Finishes shutting down the interface, after |
132 | | * H5M_top_term_package() is called |
133 | | * |
134 | | * Return: Success: Positive if anything was done that might |
135 | | * affect other interfaces; zero otherwise. |
136 | | * Failure: Negative. |
137 | | *------------------------------------------------------------------------- |
138 | | */ |
139 | | int |
140 | | H5M_term_package(void) |
141 | 1 | { |
142 | 1 | int n = 0; |
143 | | |
144 | 1 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
145 | | |
146 | | /* Sanity checks */ |
147 | 1 | assert(0 == H5I_nmembers(H5I_MAP)); |
148 | | |
149 | | /* Destroy the dataset object id group */ |
150 | 1 | n += (H5I_dec_type_ref(H5I_MAP) > 0); |
151 | | |
152 | 1 | FUNC_LEAVE_NOAPI(n) |
153 | 1 | } /* end H5M_term_package() */ |
154 | | |
155 | | /*------------------------------------------------------------------------- |
156 | | * Function: H5M__close_cb |
157 | | * |
158 | | * Purpose: Called when the ref count reaches zero on the map's ID |
159 | | * |
160 | | * Return: SUCCEED/FAIL |
161 | | * |
162 | | *------------------------------------------------------------------------- |
163 | | */ |
164 | | static herr_t |
165 | | H5M__close_cb(H5VL_object_t *map_vol_obj, void **request) |
166 | 0 | { |
167 | 0 | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
168 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
169 | |
|
170 | 0 | FUNC_ENTER_PACKAGE |
171 | | |
172 | | /* Sanity check */ |
173 | 0 | assert(map_vol_obj); |
174 | | |
175 | | /* Set up VOL callback arguments */ |
176 | 0 | vol_cb_args.op_type = H5VL_MAP_CLOSE; |
177 | 0 | vol_cb_args.args = NULL; |
178 | | |
179 | | /* Close the map */ |
180 | 0 | if (H5VL_optional(map_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, request) < 0) |
181 | 0 | HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map"); |
182 | | |
183 | | /* Free the VOL object */ |
184 | 0 | if (H5VL_free_object(map_vol_obj) < 0) |
185 | 0 | HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "unable to free VOL object"); |
186 | | |
187 | 0 | done: |
188 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
189 | 0 | } /* end H5M__close_cb() */ |
190 | | |
191 | | #ifdef H5_HAVE_MAP_API |
192 | | |
193 | | /*------------------------------------------------------------------------- |
194 | | * Function: H5M__create_api_common |
195 | | * |
196 | | * Purpose: This is the common function for creating the HDF5 map. |
197 | | * |
198 | | * Return: Success: The object ID of the new map. |
199 | | * |
200 | | * Failure: H5I_INVALID_HID |
201 | | * |
202 | | *------------------------------------------------------------------------- |
203 | | */ |
204 | | static hid_t |
205 | | H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, |
206 | | hid_t mcpl_id, hid_t mapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) |
207 | | { |
208 | | void *map = NULL; /* New map's info */ |
209 | | H5VL_object_t *tmp_vol_obj = NULL; /* Object for loc_id */ |
210 | | H5VL_object_t **vol_obj_ptr = |
211 | | (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ |
212 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
213 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
214 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
215 | | |
216 | | FUNC_ENTER_PACKAGE |
217 | | |
218 | | /* Check arguments */ |
219 | | if (!name) |
220 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL"); |
221 | | if (!*name) |
222 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string"); |
223 | | |
224 | | /* Get link creation property list */ |
225 | | if (H5P_DEFAULT == lcpl_id) |
226 | | lcpl_id = H5P_LINK_CREATE_DEFAULT; |
227 | | else if (true != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) |
228 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "lcpl_id is not a link creation property list"); |
229 | | |
230 | | /* Get map creation property list */ |
231 | | if (H5P_DEFAULT == mcpl_id) |
232 | | mcpl_id = H5P_MAP_CREATE_DEFAULT; |
233 | | else if (true != H5P_isa_class(mcpl_id, H5P_MAP_CREATE)) |
234 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID"); |
235 | | |
236 | | /* Set up VOL callback arguments */ |
237 | | if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, true, &mapl_id, vol_obj_ptr, &map_args.create.loc_params) < |
238 | | 0) |
239 | | HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments"); |
240 | | map_args.create.name = name; |
241 | | map_args.create.lcpl_id = lcpl_id; |
242 | | map_args.create.key_type_id = key_type_id; |
243 | | map_args.create.val_type_id = val_type_id; |
244 | | map_args.create.mcpl_id = mcpl_id; |
245 | | map_args.create.mapl_id = mapl_id; |
246 | | map_args.create.map = NULL; |
247 | | vol_cb_args.op_type = H5VL_MAP_CREATE; |
248 | | vol_cb_args.args = &map_args; |
249 | | |
250 | | /* Create the map */ |
251 | | if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) |
252 | | HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map"); |
253 | | map = map_args.create.map; |
254 | | |
255 | | /* Get an ID for the map */ |
256 | | if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, true)) < 0) |
257 | | HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map handle"); |
258 | | |
259 | | done: |
260 | | /* Cleanup on failure */ |
261 | | if (H5I_INVALID_HID == ret_value) { |
262 | | /* Set up VOL callback arguments */ |
263 | | vol_cb_args.op_type = H5VL_MAP_CLOSE; |
264 | | vol_cb_args.args = NULL; |
265 | | |
266 | | if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
267 | | HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map"); |
268 | | } /* end if */ |
269 | | |
270 | | FUNC_LEAVE_NOAPI(ret_value) |
271 | | } /* end H5M__create_api_common() */ |
272 | | |
273 | | /*------------------------------------------------------------------------- |
274 | | * Function: H5Mcreate |
275 | | * |
276 | | * Purpose: Creates a new map object for storing key-value pairs. The |
277 | | * in-file datatype for keys is defined by KEY_TYPE_ID and |
278 | | * the in-file datatype for values is defined by VAL_TYPE_ID. |
279 | | * LOC_ID specifies the location to create the map object and |
280 | | * NAME specifies the name of the link to the object |
281 | | * (relative to LOC_ID). Other options can be specified |
282 | | * through the property lists LCPL_ID, MCPL_ID, and MAPL_ID. |
283 | | * |
284 | | * Return: Success: The object ID of the new map. |
285 | | * |
286 | | * Failure: H5I_INVALID_HID |
287 | | * |
288 | | *------------------------------------------------------------------------- |
289 | | */ |
290 | | hid_t |
291 | | 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, |
292 | | hid_t mapl_id) |
293 | | { |
294 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
295 | | |
296 | | FUNC_ENTER_API(H5I_INVALID_HID) |
297 | | |
298 | | /* Create the map synchronously */ |
299 | | if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, |
300 | | NULL, NULL)) < 0) |
301 | | HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map synchronously"); |
302 | | |
303 | | done: |
304 | | FUNC_LEAVE_API(ret_value) |
305 | | } /* end H5Mcreate() */ |
306 | | |
307 | | /*------------------------------------------------------------------------- |
308 | | * Function: H5Mcreate_async |
309 | | * |
310 | | * Purpose: Asynchronous version of H5Mcreate |
311 | | * |
312 | | * Return: Success: The object ID of the new map. |
313 | | * |
314 | | * Failure: H5I_INVALID_HID |
315 | | * |
316 | | *------------------------------------------------------------------------- |
317 | | */ |
318 | | hid_t |
319 | | H5Mcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, |
320 | | hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, |
321 | | hid_t es_id) |
322 | | { |
323 | | H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ |
324 | | void *token = NULL; /* Request token for async operation */ |
325 | | void **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ |
326 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
327 | | |
328 | | FUNC_ENTER_API(H5I_INVALID_HID) |
329 | | |
330 | | /* Set up request token pointer for asynchronous operation */ |
331 | | if (H5ES_NONE != es_id) |
332 | | token_ptr = &token; |
333 | | |
334 | | /* Create the map asynchronously */ |
335 | | if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, |
336 | | token_ptr, &vol_obj)) < 0) |
337 | | HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map asynchronously"); |
338 | | |
339 | | /* If a token was created, add the token to the event set */ |
340 | | if (NULL != token) |
341 | | /* clang-format off */ |
342 | | if (H5ES_insert(es_id, vol_obj->connector, token, |
343 | | H5ARG_TRACE11(__func__, "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, es_id)) < 0) { |
344 | | /* clang-format on */ |
345 | | if (H5I_dec_app_ref_always_close(ret_value) < 0) |
346 | | HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID"); |
347 | | HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set"); |
348 | | } /* end if */ |
349 | | |
350 | | done: |
351 | | FUNC_LEAVE_API(ret_value) |
352 | | } /* end H5Mcreate_async() */ |
353 | | |
354 | | /*------------------------------------------------------------------------- |
355 | | * Function: H5Mcreate_anon |
356 | | * |
357 | | * Purpose: Creates a new map object for storing key-value pairs. The |
358 | | * in-file datatype for keys is defined by KEY_TYPE_ID and |
359 | | * the in-file datatype for values is defined by VAL_TYPE_ID. |
360 | | * LOC_ID specifies the file to create the map object, but no |
361 | | * link to the object is created. Other options can be |
362 | | * specified through the property lists LCPL_ID, MCPL_ID, and |
363 | | * MAPL_ID. |
364 | | * |
365 | | * The resulting ID should be linked into the file with |
366 | | * H5Olink or it will be deleted when closed. |
367 | | * |
368 | | * Return: Success: The object ID of the new map. The map should |
369 | | * be linked into the group hierarchy before being closed or |
370 | | * it will be deleted. The dataset should be |
371 | | * closed when the caller is no longer interested |
372 | | * in it. |
373 | | * |
374 | | * Failure: H5I_INVALID_HID |
375 | | * |
376 | | *------------------------------------------------------------------------- |
377 | | */ |
378 | | hid_t |
379 | | H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id) |
380 | | { |
381 | | void *map = NULL; /* map object from VOL connector */ |
382 | | H5VL_object_t *vol_obj = NULL; /* object of loc_id */ |
383 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
384 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
385 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
386 | | |
387 | | FUNC_ENTER_API(H5I_INVALID_HID) |
388 | | |
389 | | /* Check arguments */ |
390 | | if (H5P_DEFAULT == mcpl_id) |
391 | | mcpl_id = H5P_MAP_CREATE_DEFAULT; |
392 | | else if (true != H5P_isa_class(mcpl_id, H5P_MAP_CREATE)) |
393 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not map create property list ID"); |
394 | | |
395 | | /* Verify access property list and set up collective metadata if appropriate */ |
396 | | if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, true) < 0) |
397 | | HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info"); |
398 | | |
399 | | /* get the location object */ |
400 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) |
401 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier"); |
402 | | |
403 | | /* Set location parameters */ |
404 | | |
405 | | /* Set up VOL callback arguments */ |
406 | | map_args.create.loc_params.type = H5VL_OBJECT_BY_SELF; |
407 | | map_args.create.loc_params.obj_type = H5I_get_type(loc_id); |
408 | | map_args.create.name = NULL; |
409 | | map_args.create.lcpl_id = H5P_LINK_CREATE_DEFAULT; |
410 | | map_args.create.key_type_id = key_type_id; |
411 | | map_args.create.val_type_id = val_type_id; |
412 | | map_args.create.mcpl_id = mcpl_id; |
413 | | map_args.create.mapl_id = mapl_id; |
414 | | map_args.create.map = NULL; |
415 | | vol_cb_args.op_type = H5VL_MAP_CREATE; |
416 | | vol_cb_args.args = &map_args; |
417 | | |
418 | | /* Create the map */ |
419 | | if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
420 | | HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map"); |
421 | | map = map_args.create.map; |
422 | | |
423 | | /* Get an ID for the map */ |
424 | | if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, true)) < 0) |
425 | | HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map"); |
426 | | |
427 | | done: |
428 | | /* Cleanup on failure */ |
429 | | if (H5I_INVALID_HID == ret_value) { |
430 | | /* Set up VOL callback arguments */ |
431 | | vol_cb_args.op_type = H5VL_MAP_CLOSE; |
432 | | vol_cb_args.args = NULL; |
433 | | |
434 | | if (map && H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
435 | | HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map"); |
436 | | } /* end if */ |
437 | | |
438 | | FUNC_LEAVE_API(ret_value) |
439 | | } /* end H5Mcreate_anon() */ |
440 | | |
441 | | /*------------------------------------------------------------------------ |
442 | | * Function: H5M__open_api_common |
443 | | * |
444 | | * Purpose: This is the common function for opening the HDF5 map. |
445 | | * |
446 | | * Return: Success: Object ID of the map |
447 | | * |
448 | | * Failure: H5I_INVALID_HID |
449 | | * |
450 | | *------------------------------------------------------------------------- |
451 | | */ |
452 | | static hid_t |
453 | | H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr, |
454 | | H5VL_object_t **_vol_obj_ptr) |
455 | | { |
456 | | void *map = NULL; /* map object from VOL connector */ |
457 | | H5VL_object_t *tmp_vol_obj = NULL; /* Object for loc_id */ |
458 | | H5VL_object_t **vol_obj_ptr = |
459 | | (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ |
460 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
461 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
462 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
463 | | |
464 | | FUNC_ENTER_PACKAGE |
465 | | |
466 | | /* Check args */ |
467 | | if (!name) |
468 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL"); |
469 | | if (!*name) |
470 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string"); |
471 | | |
472 | | /* Set up VOL callback arguments */ |
473 | | if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, false, &mapl_id, vol_obj_ptr, &map_args.open.loc_params) < |
474 | | 0) |
475 | | HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments"); |
476 | | map_args.open.name = name; |
477 | | map_args.open.mapl_id = mapl_id; |
478 | | map_args.open.map = NULL; |
479 | | vol_cb_args.op_type = H5VL_MAP_OPEN; |
480 | | vol_cb_args.args = &map_args; |
481 | | |
482 | | /* Open the map */ |
483 | | if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) |
484 | | HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map"); |
485 | | map = map_args.open.map; |
486 | | |
487 | | /* Register an ID for the map */ |
488 | | if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, true)) < 0) |
489 | | HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register map ID"); |
490 | | |
491 | | done: |
492 | | /* Cleanup on failure */ |
493 | | if (H5I_INVALID_HID == ret_value) { |
494 | | /* Set up VOL callback arguments */ |
495 | | vol_cb_args.op_type = H5VL_MAP_CLOSE; |
496 | | vol_cb_args.args = NULL; |
497 | | |
498 | | if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
499 | | HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map"); |
500 | | } /* end if */ |
501 | | |
502 | | FUNC_LEAVE_NOAPI(ret_value) |
503 | | } /* end H5M__open_api_common() */ |
504 | | |
505 | | /*------------------------------------------------------------------------ |
506 | | * Function: H5Mopen |
507 | | * |
508 | | * Purpose: Finds a map named NAME at LOC_ID, opens it, and returns |
509 | | * its ID. The map should be close when the caller is no |
510 | | * longer interested in it. |
511 | | * |
512 | | * Takes a map access property list |
513 | | * |
514 | | * Return: Success: Object ID of the map |
515 | | * |
516 | | * Failure: H5I_INVALID_HID |
517 | | * |
518 | | *------------------------------------------------------------------------- |
519 | | */ |
520 | | hid_t |
521 | | H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) |
522 | | { |
523 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
524 | | |
525 | | FUNC_ENTER_API(H5I_INVALID_HID) |
526 | | |
527 | | /* Open the map synchronously */ |
528 | | if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, NULL, NULL)) < 0) |
529 | | HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map synchronously"); |
530 | | |
531 | | done: |
532 | | FUNC_LEAVE_API(ret_value) |
533 | | } /* end H5Mopen() */ |
534 | | |
535 | | /*------------------------------------------------------------------------ |
536 | | * Function: H5Mopen_async |
537 | | * |
538 | | * Purpose: Asynchronous version of H5Mopen |
539 | | * |
540 | | * Return: Success: Object ID of the map |
541 | | * |
542 | | * Failure: H5I_INVALID_HID |
543 | | * |
544 | | *------------------------------------------------------------------------- |
545 | | */ |
546 | | hid_t |
547 | | H5Mopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, |
548 | | hid_t mapl_id, hid_t es_id) |
549 | | { |
550 | | H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ |
551 | | void *token = NULL; /* Request token for async operation */ |
552 | | void **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ |
553 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
554 | | |
555 | | FUNC_ENTER_API(H5I_INVALID_HID) |
556 | | |
557 | | /* Set up request token pointer for asynchronous operation */ |
558 | | if (H5ES_NONE != es_id) |
559 | | token_ptr = &token; |
560 | | |
561 | | /* Open the map asynchronously */ |
562 | | if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, token_ptr, &vol_obj)) < 0) |
563 | | HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map asynchronously"); |
564 | | |
565 | | /* If a token was created, add the token to the event set */ |
566 | | if (NULL != token) |
567 | | /* clang-format off */ |
568 | | if (H5ES_insert(es_id, vol_obj->connector, token, |
569 | | H5ARG_TRACE7(__func__, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id, es_id)) < 0) { |
570 | | /* clang-format on */ |
571 | | if (H5I_dec_app_ref_always_close(ret_value) < 0) |
572 | | HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID"); |
573 | | HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set"); |
574 | | } /* end if */ |
575 | | |
576 | | done: |
577 | | FUNC_LEAVE_API(ret_value) |
578 | | } /* end H5Mopen_async() */ |
579 | | |
580 | | /*------------------------------------------------------------------------- |
581 | | * Function: H5Mclose |
582 | | * |
583 | | * Purpose: Closes access to a map and releases resources used by it. |
584 | | * It is illegal to subsequently use that same map ID in |
585 | | * calls to other map functions. |
586 | | * |
587 | | * Return: SUCCEED/FAIL |
588 | | * |
589 | | *------------------------------------------------------------------------- |
590 | | */ |
591 | | herr_t |
592 | | H5Mclose(hid_t map_id) |
593 | | { |
594 | | herr_t ret_value = SUCCEED; /* Return value */ |
595 | | |
596 | | FUNC_ENTER_API(FAIL) |
597 | | |
598 | | /* Check args */ |
599 | | if (H5I_MAP != H5I_get_type(map_id)) |
600 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID"); |
601 | | |
602 | | /* Decrement the counter on the map. It will be freed if the count |
603 | | * reaches zero. |
604 | | */ |
605 | | if (H5I_dec_app_ref_always_close(map_id) < 0) |
606 | | HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on map ID"); |
607 | | |
608 | | done: |
609 | | FUNC_LEAVE_API(ret_value) |
610 | | } /* end H5Mclose() */ |
611 | | |
612 | | /*------------------------------------------------------------------------- |
613 | | * Function: H5Mclose_async |
614 | | * |
615 | | * Purpose: Asynchronous version of H5Mclose |
616 | | * |
617 | | * Return: SUCCEED/FAIL |
618 | | * |
619 | | *------------------------------------------------------------------------- |
620 | | */ |
621 | | herr_t |
622 | | H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t es_id) |
623 | | { |
624 | | void *token = NULL; /* Request token for async operation */ |
625 | | void **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ |
626 | | H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */ |
627 | | H5VL_t *connector = NULL; /* VOL connector */ |
628 | | herr_t ret_value = SUCCEED; /* Return value */ |
629 | | |
630 | | FUNC_ENTER_API(FAIL) |
631 | | |
632 | | /* Check args */ |
633 | | if (H5I_MAP != H5I_get_type(map_id)) |
634 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID"); |
635 | | |
636 | | /* Get map object's connector */ |
637 | | if (NULL == (vol_obj = H5VL_vol_object(map_id))) |
638 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get VOL object for map"); |
639 | | |
640 | | /* Prepare for possible asynchronous operation */ |
641 | | if (H5ES_NONE != es_id) { |
642 | | /* Increase connector's refcount, so it doesn't get closed if closing |
643 | | * the dataset closes the file */ |
644 | | connector = vol_obj->connector; |
645 | | H5VL_conn_inc_rc(connector); |
646 | | |
647 | | /* Point at token for operation to set up */ |
648 | | token_ptr = &token; |
649 | | } /* end if */ |
650 | | |
651 | | /* Decrement the counter on the map. It will be freed if the count |
652 | | * reaches zero. |
653 | | */ |
654 | | if (H5I_dec_app_ref_always_close_async(map_id, token_ptr) < 0) |
655 | | HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID"); |
656 | | |
657 | | /* If a token was created, add the token to the event set */ |
658 | | if (NULL != token) |
659 | | /* clang-format off */ |
660 | | if (H5ES_insert(es_id, vol_obj->connector, token, |
661 | | H5ARG_TRACE5(__func__, "*s*sIuii", app_file, app_func, app_line, map_id, es_id)) < 0) |
662 | | /* clang-format on */ |
663 | | HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set"); |
664 | | |
665 | | done: |
666 | | if (connector && H5VL_conn_dec_rc(connector) < 0) |
667 | | HDONE_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement ref count on connector"); |
668 | | |
669 | | FUNC_LEAVE_API(ret_value) |
670 | | } /* end H5Mclose_async() */ |
671 | | |
672 | | /*------------------------------------------------------------------------- |
673 | | * Function: H5Mget_key_type |
674 | | * |
675 | | * Purpose: Returns a copy of the key datatype for a map. |
676 | | * |
677 | | * Return: Success: ID for a copy of the datatype. The data |
678 | | * type should be released by calling |
679 | | * H5Tclose(). |
680 | | * |
681 | | * Failure: H5I_INVALID_HID |
682 | | * |
683 | | *------------------------------------------------------------------------- |
684 | | */ |
685 | | hid_t |
686 | | H5Mget_key_type(hid_t map_id) |
687 | | { |
688 | | H5VL_object_t *vol_obj; /* Map structure */ |
689 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
690 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
691 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
692 | | |
693 | | FUNC_ENTER_API(H5I_INVALID_HID) |
694 | | |
695 | | /* Check args */ |
696 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
697 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier"); |
698 | | |
699 | | /* Set up VOL callback arguments */ |
700 | | map_args.get.get_type = H5VL_MAP_GET_KEY_TYPE; |
701 | | map_args.get.args.get_key_type.type_id = H5I_INVALID_HID; |
702 | | vol_cb_args.op_type = H5VL_MAP_GET; |
703 | | vol_cb_args.args = &map_args; |
704 | | |
705 | | /* Get the key datatype */ |
706 | | if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
707 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get key datatype"); |
708 | | |
709 | | /* Set return value */ |
710 | | ret_value = map_args.get.args.get_key_type.type_id; |
711 | | |
712 | | done: |
713 | | FUNC_LEAVE_API(ret_value) |
714 | | } /* end H5Mget_key_type() */ |
715 | | |
716 | | /*------------------------------------------------------------------------- |
717 | | * Function: H5Mget_val_type |
718 | | * |
719 | | * Purpose: Returns a copy of the value datatype for a map. |
720 | | * |
721 | | * Return: Success: ID for a copy of the datatype. The data |
722 | | * type should be released by calling |
723 | | * H5Tclose(). |
724 | | * |
725 | | * Failure: H5I_INVALID_HID |
726 | | * |
727 | | *------------------------------------------------------------------------- |
728 | | */ |
729 | | hid_t |
730 | | H5Mget_val_type(hid_t map_id) |
731 | | { |
732 | | H5VL_object_t *vol_obj; /* Map structure */ |
733 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
734 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
735 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
736 | | |
737 | | FUNC_ENTER_API(H5I_INVALID_HID) |
738 | | |
739 | | /* Check args */ |
740 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
741 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier"); |
742 | | |
743 | | /* Set up VOL callback arguments */ |
744 | | map_args.get.get_type = H5VL_MAP_GET_VAL_TYPE; |
745 | | map_args.get.args.get_val_type.type_id = H5I_INVALID_HID; |
746 | | vol_cb_args.op_type = H5VL_MAP_GET; |
747 | | vol_cb_args.args = &map_args; |
748 | | |
749 | | /* Get the value datatype */ |
750 | | if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
751 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get value datatype"); |
752 | | |
753 | | /* Set return value */ |
754 | | ret_value = map_args.get.args.get_val_type.type_id; |
755 | | |
756 | | done: |
757 | | FUNC_LEAVE_API(ret_value) |
758 | | } /* end H5Mget_val_type() */ |
759 | | |
760 | | /*------------------------------------------------------------------------- |
761 | | * Function: H5Mget_create_plist |
762 | | * |
763 | | * Purpose: Returns a copy of the map creation property list. |
764 | | * |
765 | | * Return: Success: ID for a copy of the map creation |
766 | | * property list. The template should be |
767 | | * released by calling H5P_close(). |
768 | | * |
769 | | * Failure: H5I_INVALID_HID |
770 | | * |
771 | | *------------------------------------------------------------------------- |
772 | | */ |
773 | | hid_t |
774 | | H5Mget_create_plist(hid_t map_id) |
775 | | { |
776 | | H5VL_object_t *vol_obj; /* Map structure */ |
777 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
778 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
779 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
780 | | |
781 | | FUNC_ENTER_API(H5I_INVALID_HID) |
782 | | |
783 | | /* Check args */ |
784 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
785 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier"); |
786 | | |
787 | | /* Set up VOL callback arguments */ |
788 | | map_args.get.get_type = H5VL_MAP_GET_MCPL; |
789 | | map_args.get.args.get_mcpl.mcpl_id = H5I_INVALID_HID; |
790 | | vol_cb_args.op_type = H5VL_MAP_GET; |
791 | | vol_cb_args.args = &map_args; |
792 | | |
793 | | /* Get the map creation property list */ |
794 | | if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
795 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map creation properties"); |
796 | | |
797 | | /* Set return value */ |
798 | | ret_value = map_args.get.args.get_mcpl.mcpl_id; |
799 | | |
800 | | done: |
801 | | FUNC_LEAVE_API(ret_value) |
802 | | } /* end H5Mget_create_plist() */ |
803 | | |
804 | | /*------------------------------------------------------------------------- |
805 | | * Function: H5Mget_access_plist |
806 | | * |
807 | | * Purpose: Returns a copy of the map access property list. |
808 | | * |
809 | | * Description: H5Mget_access_plist returns the map access property |
810 | | * list identifier of the specified map. |
811 | | * |
812 | | * Return: Success: ID for a copy of the map access |
813 | | * property list. The template should be |
814 | | * released by calling H5Pclose(). |
815 | | * |
816 | | * Failure: H5I_INVALID_HID |
817 | | * |
818 | | *------------------------------------------------------------------------- |
819 | | */ |
820 | | hid_t |
821 | | H5Mget_access_plist(hid_t map_id) |
822 | | { |
823 | | H5VL_object_t *vol_obj; /* Map structure */ |
824 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
825 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
826 | | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
827 | | |
828 | | FUNC_ENTER_API(H5I_INVALID_HID) |
829 | | |
830 | | /* Check args */ |
831 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
832 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier"); |
833 | | |
834 | | /* Set up VOL callback arguments */ |
835 | | map_args.get.get_type = H5VL_MAP_GET_MAPL; |
836 | | map_args.get.args.get_mapl.mapl_id = H5I_INVALID_HID; |
837 | | vol_cb_args.op_type = H5VL_MAP_GET; |
838 | | vol_cb_args.args = &map_args; |
839 | | |
840 | | /* Get the map access property list */ |
841 | | if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
842 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties"); |
843 | | |
844 | | /* Set return value */ |
845 | | ret_value = map_args.get.args.get_mapl.mapl_id; |
846 | | |
847 | | done: |
848 | | FUNC_LEAVE_API(ret_value) |
849 | | } /* end H5Mget_access_plist() */ |
850 | | |
851 | | /*------------------------------------------------------------------------- |
852 | | * Function: H5Mget_count |
853 | | * |
854 | | * Purpose: Returns the number of key-value pairs stored in the map. |
855 | | * |
856 | | * Description: H5Mget_count returns the number of key-value pairs stored |
857 | | * in the specified map. |
858 | | * |
859 | | * Return: SUCCEED/FAIL |
860 | | * |
861 | | *------------------------------------------------------------------------- |
862 | | */ |
863 | | herr_t |
864 | | H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id) |
865 | | { |
866 | | H5VL_object_t *vol_obj; /* Map structure */ |
867 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
868 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
869 | | herr_t ret_value = SUCCEED; /* Return value */ |
870 | | |
871 | | FUNC_ENTER_API(H5I_INVALID_HID) |
872 | | |
873 | | /* Check args */ |
874 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
875 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier"); |
876 | | |
877 | | /* Get the default dataset transfer property list if the user didn't provide one */ |
878 | | if (H5P_DEFAULT == dxpl_id) |
879 | | dxpl_id = H5P_DATASET_XFER_DEFAULT; |
880 | | else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) |
881 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); |
882 | | |
883 | | /* Set up VOL callback arguments */ |
884 | | map_args.get.get_type = H5VL_MAP_GET_COUNT; |
885 | | map_args.get.args.get_count.count = 0; |
886 | | vol_cb_args.op_type = H5VL_MAP_GET; |
887 | | vol_cb_args.args = &map_args; |
888 | | |
889 | | /* Get the number of key-value pairs stored in the map */ |
890 | | if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) |
891 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get KV pair count for map"); |
892 | | |
893 | | /* Set value to return */ |
894 | | if (count) |
895 | | *count = map_args.get.args.get_count.count; |
896 | | |
897 | | done: |
898 | | FUNC_LEAVE_API(ret_value) |
899 | | } /* end H5Mget_count() */ |
900 | | |
901 | | /*------------------------------------------------------------------------- |
902 | | * Function: H5M__put_api_common |
903 | | * |
904 | | * Purpose: This is the common function for putting value to map. |
905 | | * |
906 | | * Return: SUCCEED/FAIL |
907 | | * |
908 | | *------------------------------------------------------------------------- |
909 | | */ |
910 | | static herr_t |
911 | | H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, |
912 | | const void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) |
913 | | { |
914 | | H5VL_object_t *tmp_vol_obj = NULL; /* Object for loc_id */ |
915 | | H5VL_object_t **vol_obj_ptr = |
916 | | (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ |
917 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
918 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
919 | | herr_t ret_value = SUCCEED; /* Return value */ |
920 | | |
921 | | FUNC_ENTER_PACKAGE |
922 | | |
923 | | /* Check arguments */ |
924 | | if (key_mem_type_id < 0) |
925 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID"); |
926 | | if (val_mem_type_id < 0) |
927 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID"); |
928 | | |
929 | | /* Get map pointer */ |
930 | | if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
931 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID"); |
932 | | |
933 | | /* Get the default dataset transfer property list if the user didn't provide one */ |
934 | | if (H5P_DEFAULT == dxpl_id) |
935 | | dxpl_id = H5P_DATASET_XFER_DEFAULT; |
936 | | else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) |
937 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); |
938 | | |
939 | | /* Set up VOL callback arguments */ |
940 | | map_args.put.key_mem_type_id = key_mem_type_id; |
941 | | map_args.put.key = key; |
942 | | map_args.put.value_mem_type_id = val_mem_type_id; |
943 | | map_args.put.value = value; |
944 | | vol_cb_args.op_type = H5VL_MAP_PUT; |
945 | | vol_cb_args.args = &map_args; |
946 | | |
947 | | /* Set the key/value pair */ |
948 | | if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0) |
949 | | HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair"); |
950 | | |
951 | | done: |
952 | | FUNC_LEAVE_NOAPI(ret_value) |
953 | | } /* end H5M__put_api_common() */ |
954 | | |
955 | | /*------------------------------------------------------------------------- |
956 | | * Function: H5Mput |
957 | | * |
958 | | * Purpose: H5Mput adds a key-value pair to the Map specified by |
959 | | * MAP_ID, or updates the value for the specified key if one |
960 | | * was set previously. KEY_MEM_TYPE_ID and VAL_MEM_TYPE_ID |
961 | | * specify the datatypes for the provided KEY and VALUE |
962 | | * buffers, and if different from those used to create the |
963 | | * map object, the key and value will be internally converted |
964 | | * to the datatypes for the map object. Any further options |
965 | | * can be specified through the property list DXPL_ID. |
966 | | * |
967 | | * Return: SUCCEED/FAIL |
968 | | * |
969 | | *------------------------------------------------------------------------- |
970 | | */ |
971 | | herr_t |
972 | | H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, |
973 | | hid_t dxpl_id) |
974 | | { |
975 | | herr_t ret_value = SUCCEED; /* Return value */ |
976 | | |
977 | | FUNC_ENTER_API(FAIL) |
978 | | |
979 | | /* Add key-value pair to the map synchronously */ |
980 | | if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL, |
981 | | NULL)) < 0) |
982 | | HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map synchronously"); |
983 | | |
984 | | done: |
985 | | FUNC_LEAVE_API(ret_value) |
986 | | } /* end H5Mput() */ |
987 | | |
988 | | /*------------------------------------------------------------------------- |
989 | | * Function: H5Mput_async |
990 | | * |
991 | | * Purpose: Asynchronous version of H5Mput |
992 | | * |
993 | | * Return: SUCCEED/FAIL |
994 | | * |
995 | | *------------------------------------------------------------------------- |
996 | | */ |
997 | | herr_t |
998 | | H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, |
999 | | hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id, |
1000 | | hid_t es_id) |
1001 | | { |
1002 | | H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ |
1003 | | void *token = NULL; /* Request token for async operation */ |
1004 | | void **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ |
1005 | | herr_t ret_value = SUCCEED; /* Return value */ |
1006 | | |
1007 | | FUNC_ENTER_API(FAIL) |
1008 | | |
1009 | | /* Set up request token pointer for asynchronous operation */ |
1010 | | if (H5ES_NONE != es_id) |
1011 | | token_ptr = &token; |
1012 | | |
1013 | | /* Add key-value pair to the map asynchronously */ |
1014 | | if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, |
1015 | | token_ptr, &vol_obj)) < 0) |
1016 | | HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map asynchronously"); |
1017 | | |
1018 | | /* If a token was created, add the token to the event set */ |
1019 | | if (NULL != token) |
1020 | | /* clang-format off */ |
1021 | | if (H5ES_insert(es_id, vol_obj->connector, token, |
1022 | | H5ARG_TRACE10(__func__, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0) |
1023 | | /* clang-format on */ |
1024 | | HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set"); |
1025 | | |
1026 | | done: |
1027 | | FUNC_LEAVE_API(ret_value) |
1028 | | } /* end H5Mput_async() */ |
1029 | | |
1030 | | /*------------------------------------------------------------------------- |
1031 | | * Function: H5M__get_api_common |
1032 | | * |
1033 | | * Purpose: This is common function for getting value from the map. |
1034 | | * |
1035 | | * Return: SUCCEED/FAIL |
1036 | | * |
1037 | | *------------------------------------------------------------------------- |
1038 | | */ |
1039 | | static herr_t |
1040 | | H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, |
1041 | | hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) |
1042 | | { |
1043 | | H5VL_object_t *tmp_vol_obj = NULL; /* Object for loc_id */ |
1044 | | H5VL_object_t **vol_obj_ptr = |
1045 | | (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ |
1046 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
1047 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
1048 | | herr_t ret_value = SUCCEED; /* Return value */ |
1049 | | |
1050 | | FUNC_ENTER_PACKAGE |
1051 | | |
1052 | | /* Check arguments */ |
1053 | | if (key_mem_type_id < 0) |
1054 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID"); |
1055 | | if (val_mem_type_id < 0) |
1056 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID"); |
1057 | | |
1058 | | /* Get map pointer */ |
1059 | | if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
1060 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID"); |
1061 | | |
1062 | | /* Get the default dataset transfer property list if the user didn't provide one */ |
1063 | | if (H5P_DEFAULT == dxpl_id) |
1064 | | dxpl_id = H5P_DATASET_XFER_DEFAULT; |
1065 | | else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) |
1066 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); |
1067 | | |
1068 | | /* Set up VOL callback arguments */ |
1069 | | map_args.get_val.key_mem_type_id = key_mem_type_id; |
1070 | | map_args.get_val.key = key; |
1071 | | map_args.get_val.value_mem_type_id = val_mem_type_id; |
1072 | | map_args.get_val.value = value; |
1073 | | vol_cb_args.op_type = H5VL_MAP_GET_VAL; |
1074 | | vol_cb_args.args = &map_args; |
1075 | | |
1076 | | /* Get the value for the key */ |
1077 | | if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0) |
1078 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map"); |
1079 | | |
1080 | | done: |
1081 | | FUNC_LEAVE_NOAPI(ret_value) |
1082 | | } /* end H5M__get_api_common() */ |
1083 | | |
1084 | | /*------------------------------------------------------------------------- |
1085 | | * Function: H5Mget |
1086 | | * |
1087 | | * Purpose: H5Mget retrieves, from the Map specified by MAP_ID, the |
1088 | | * value associated with the provided key. KEY_MEM_TYPE_ID |
1089 | | * and VAL_MEM_TYPE_ID specify the datatypes for the provided |
1090 | | * KEY and VALUE buffers. If KEY_MEM_TYPE_ID is different |
1091 | | * from that used to create the map object, the key will be |
1092 | | * internally converted to the datatype for the map object |
1093 | | * for the query, and if VAL_MEM_TYPE_ID is different from |
1094 | | * that used to create the map object, the returned value |
1095 | | * will be converted to VAL_MEM_TYPE_ID before the function |
1096 | | * returns. Any further options can be specified through the |
1097 | | * property list DXPL_ID. |
1098 | | * |
1099 | | * Return: SUCCEED/FAIL |
1100 | | * |
1101 | | *------------------------------------------------------------------------- |
1102 | | */ |
1103 | | herr_t |
1104 | | H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, |
1105 | | hid_t dxpl_id) |
1106 | | { |
1107 | | herr_t ret_value = SUCCEED; /* Return value */ |
1108 | | |
1109 | | FUNC_ENTER_API(FAIL) |
1110 | | |
1111 | | /* Get key-value pair from the map synchronously */ |
1112 | | if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL, |
1113 | | NULL)) < 0) |
1114 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map synchronously"); |
1115 | | |
1116 | | done: |
1117 | | FUNC_LEAVE_API(ret_value) |
1118 | | } /* end H5Mget() */ |
1119 | | |
1120 | | /*------------------------------------------------------------------------- |
1121 | | * Function: H5Mget_async |
1122 | | * |
1123 | | * Purpose: Asynchronous version of H5Mget |
1124 | | * |
1125 | | * Return: SUCCEED/FAIL |
1126 | | * |
1127 | | *------------------------------------------------------------------------- |
1128 | | */ |
1129 | | herr_t |
1130 | | H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, |
1131 | | hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id, |
1132 | | hid_t es_id) |
1133 | | { |
1134 | | H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ |
1135 | | void *token = NULL; /* Request token for async operation */ |
1136 | | void **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ |
1137 | | herr_t ret_value = SUCCEED; /* Return value */ |
1138 | | |
1139 | | FUNC_ENTER_API(FAIL) |
1140 | | |
1141 | | /* Set up request token pointer for asynchronous operation */ |
1142 | | if (H5ES_NONE != es_id) |
1143 | | token_ptr = &token; |
1144 | | |
1145 | | /* Get key-value pair from the map asynchronously */ |
1146 | | if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, |
1147 | | token_ptr, &vol_obj)) < 0) |
1148 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map asynchronously"); |
1149 | | |
1150 | | /* If a token was created, add the token to the event set */ |
1151 | | if (NULL != token) |
1152 | | /* clang-format off */ |
1153 | | if (H5ES_insert(es_id, vol_obj->connector, token, |
1154 | | H5ARG_TRACE10(__func__, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0) |
1155 | | /* clang-format on */ |
1156 | | HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set"); |
1157 | | |
1158 | | done: |
1159 | | FUNC_LEAVE_API(ret_value) |
1160 | | } /* end H5Mget_async() */ |
1161 | | |
1162 | | /*------------------------------------------------------------------------- |
1163 | | * Function: H5Mexists |
1164 | | * |
1165 | | * Purpose: H5Mexists checks if the provided key is stored in the map |
1166 | | * specified by MAP_ID. If KEY_MEM_TYPE_ID is different from |
1167 | | * that used to create the map object the key will be |
1168 | | * internally converted to the datatype for the map object |
1169 | | * for the query. |
1170 | | * |
1171 | | * Return: SUCCEED/FAIL |
1172 | | * |
1173 | | *------------------------------------------------------------------------- |
1174 | | */ |
1175 | | herr_t |
1176 | | H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id) |
1177 | | { |
1178 | | H5VL_object_t *vol_obj = NULL; |
1179 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
1180 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
1181 | | herr_t ret_value = SUCCEED; /* Return value */ |
1182 | | |
1183 | | FUNC_ENTER_API(FAIL) |
1184 | | |
1185 | | /* Check arguments */ |
1186 | | if (key_mem_type_id < 0) |
1187 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID"); |
1188 | | |
1189 | | /* Get map pointer */ |
1190 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
1191 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID"); |
1192 | | |
1193 | | /* Get the default dataset transfer property list if the user didn't provide one */ |
1194 | | if (H5P_DEFAULT == dxpl_id) |
1195 | | dxpl_id = H5P_DATASET_XFER_DEFAULT; |
1196 | | else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) |
1197 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); |
1198 | | |
1199 | | /* Set up VOL callback arguments */ |
1200 | | map_args.exists.key_mem_type_id = key_mem_type_id; |
1201 | | map_args.exists.key = key; |
1202 | | map_args.exists.exists = false; |
1203 | | vol_cb_args.op_type = H5VL_MAP_EXISTS; |
1204 | | vol_cb_args.args = &map_args; |
1205 | | |
1206 | | /* Check if key exists */ |
1207 | | if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) |
1208 | | HGOTO_ERROR(H5E_MAP, H5E_CANTGET, ret_value, "unable to check if key exists"); |
1209 | | |
1210 | | /* Set value to return */ |
1211 | | if (exists) |
1212 | | *exists = map_args.exists.exists; |
1213 | | |
1214 | | done: |
1215 | | FUNC_LEAVE_API(ret_value) |
1216 | | } /* end H5Mexists() */ |
1217 | | |
1218 | | /*------------------------------------------------------------------------- |
1219 | | * Function: H5Miterate |
1220 | | * |
1221 | | * Purpose: H5Miterate iterates over all key-value pairs stored in the |
1222 | | * map specified by MAP_ID, making the callback specified by |
1223 | | * OP for each. The IDX parameter is an in/out parameter that |
1224 | | * may be used to restart a previously interrupted iteration. |
1225 | | * At the start of iteration IDX should be set to 0, and to |
1226 | | * restart iteration at the same location on a subsequent |
1227 | | * call to H5Miterate, IDX should be the same value as |
1228 | | * returned by the previous call. |
1229 | | * |
1230 | | * H5M_iterate_t is defined as: |
1231 | | * herr_t (*H5M_iterate_t)(hid_t map_id, const void *key, |
1232 | | * void *ctx) |
1233 | | * |
1234 | | * The KEY parameter is the buffer for the key for this |
1235 | | * iteration, converted to the datatype specified by |
1236 | | * KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass |
1237 | | * through of the value passed to H5Miterate, which can be |
1238 | | * used to store application-defined data for iteration. A |
1239 | | * negative return value from this function will cause |
1240 | | * H5Miterate to issue an error, while a positive return |
1241 | | * value will cause H5Miterate to stop iterating and return |
1242 | | * this value without issuing an error. A return value of |
1243 | | * zero allows iteration to continue. |
1244 | | * |
1245 | | * Return: Last value returned by op |
1246 | | * |
1247 | | *------------------------------------------------------------------------- |
1248 | | */ |
1249 | | herr_t |
1250 | | 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) |
1251 | | { |
1252 | | H5VL_object_t *vol_obj = NULL; |
1253 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
1254 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
1255 | | herr_t ret_value = SUCCEED; /* Return value */ |
1256 | | |
1257 | | FUNC_ENTER_API(FAIL) |
1258 | | |
1259 | | /* Check arguments */ |
1260 | | if (key_mem_type_id < 0) |
1261 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID"); |
1262 | | if (!op) |
1263 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified"); |
1264 | | |
1265 | | /* Get map pointer */ |
1266 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
1267 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID"); |
1268 | | |
1269 | | /* Get the default dataset transfer property list if the user didn't provide one */ |
1270 | | if (H5P_DEFAULT == dxpl_id) |
1271 | | dxpl_id = H5P_DATASET_XFER_DEFAULT; |
1272 | | else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) |
1273 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); |
1274 | | |
1275 | | /* Set up VOL callback arguments */ |
1276 | | map_args.specific.specific_type = H5VL_MAP_ITER; |
1277 | | map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_SELF; |
1278 | | map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(map_id); |
1279 | | map_args.specific.args.iterate.idx = (idx ? *idx : 0); |
1280 | | map_args.specific.args.iterate.key_mem_type_id = key_mem_type_id; |
1281 | | map_args.specific.args.iterate.op = op; |
1282 | | map_args.specific.args.iterate.op_data = op_data; |
1283 | | vol_cb_args.op_type = H5VL_MAP_SPECIFIC; |
1284 | | vol_cb_args.args = &map_args; |
1285 | | |
1286 | | /* Iterate over keys */ |
1287 | | if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) |
1288 | | HERROR(H5E_MAP, H5E_BADITER, "unable to iterate over keys"); |
1289 | | |
1290 | | /* Set value to return */ |
1291 | | if (idx) |
1292 | | *idx = map_args.specific.args.iterate.idx; |
1293 | | |
1294 | | done: |
1295 | | FUNC_LEAVE_API(ret_value) |
1296 | | } /* end H5Miterate() */ |
1297 | | |
1298 | | /*------------------------------------------------------------------------- |
1299 | | * Function: H5Miterate_by_name |
1300 | | * |
1301 | | * Purpose: H5Miterate_by_name iterates over all key-value pairs |
1302 | | * stored in the map specified by MAP_ID, making the callback |
1303 | | * specified by OP for each. The IDX parameter is an in/out |
1304 | | * parameter that may be used to restart a previously |
1305 | | * interrupted iteration. At the start of iteration IDX |
1306 | | * should be set to 0, and to restart iteration at the same |
1307 | | * location on a subsequent call to H5Miterate, IDX should be |
1308 | | * the same value as returned by the previous call. |
1309 | | * |
1310 | | * H5M_iterate_t is defined as: |
1311 | | * herr_t (*H5M_iterate_t)(hid_t map_id, const void *key, |
1312 | | * void *ctx) |
1313 | | * |
1314 | | * The KEY parameter is the buffer for the key for this |
1315 | | * iteration, converted to the datatype specified by |
1316 | | * KEY_MEM_TYPE_ID. The OP_DATA parameter is a simple pass |
1317 | | * through of the value passed to H5Miterate, which can be |
1318 | | * used to store application-defined data for iteration. A |
1319 | | * negative return value from this function will cause |
1320 | | * H5Miterate to issue an error, while a positive return |
1321 | | * value will cause H5Miterate to stop iterating and return |
1322 | | * this value without issuing an error. A return value of |
1323 | | * zero allows iteration to continue. |
1324 | | * |
1325 | | * Return: Last value returned by op |
1326 | | * |
1327 | | *------------------------------------------------------------------------- |
1328 | | */ |
1329 | | herr_t |
1330 | | H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, |
1331 | | void *op_data, hid_t dxpl_id, hid_t lapl_id) |
1332 | | { |
1333 | | H5VL_object_t *vol_obj = NULL; |
1334 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
1335 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
1336 | | herr_t ret_value = SUCCEED; /* Return value */ |
1337 | | |
1338 | | FUNC_ENTER_API(FAIL) |
1339 | | |
1340 | | /* Check arguments */ |
1341 | | if (!map_name) |
1342 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be NULL"); |
1343 | | if (!*map_name) |
1344 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "map_name parameter cannot be an empty string"); |
1345 | | if (key_mem_type_id < 0) |
1346 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID"); |
1347 | | if (!op) |
1348 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified"); |
1349 | | |
1350 | | /* Get the location object */ |
1351 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) |
1352 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier"); |
1353 | | |
1354 | | /* Get the default dataset transfer property list if the user didn't provide one */ |
1355 | | if (H5P_DEFAULT == dxpl_id) |
1356 | | dxpl_id = H5P_DATASET_XFER_DEFAULT; |
1357 | | else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) |
1358 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); |
1359 | | |
1360 | | /* Set up VOL callback arguments */ |
1361 | | map_args.specific.specific_type = H5VL_MAP_ITER; |
1362 | | map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_NAME; |
1363 | | map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(loc_id); |
1364 | | map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.name = map_name; |
1365 | | map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.lapl_id = lapl_id; |
1366 | | map_args.specific.args.iterate.idx = (idx ? *idx : 0); |
1367 | | map_args.specific.args.iterate.key_mem_type_id = key_mem_type_id; |
1368 | | map_args.specific.args.iterate.op = op; |
1369 | | map_args.specific.args.iterate.op_data = op_data; |
1370 | | vol_cb_args.op_type = H5VL_MAP_SPECIFIC; |
1371 | | vol_cb_args.args = &map_args; |
1372 | | |
1373 | | /* Iterate over keys */ |
1374 | | if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) |
1375 | | HERROR(H5E_MAP, H5E_BADITER, "unable to ierate over keys"); |
1376 | | |
1377 | | /* Set value to return */ |
1378 | | if (idx) |
1379 | | *idx = map_args.specific.args.iterate.idx; |
1380 | | |
1381 | | done: |
1382 | | FUNC_LEAVE_API(ret_value) |
1383 | | } /* end H5Miterate_by_name() */ |
1384 | | |
1385 | | /*------------------------------------------------------------------------- |
1386 | | * Function: H5Mdelete |
1387 | | * |
1388 | | * Purpose: H5Mdelete deletes a key-value pair from the Map |
1389 | | * specified by MAP_ID. KEY_MEM_TYPE_ID specifies the |
1390 | | * datatype for the provided key buffers, and if different |
1391 | | * from that used to create the Map object, the key will be |
1392 | | * internally converted to the datatype for the map object. |
1393 | | * Any further options can be specified through the property |
1394 | | * list DXPL_ID. |
1395 | | * |
1396 | | * Return: SUCCEED/FAIL |
1397 | | * |
1398 | | *------------------------------------------------------------------------- |
1399 | | */ |
1400 | | herr_t |
1401 | | H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id) |
1402 | | { |
1403 | | H5VL_object_t *vol_obj = NULL; |
1404 | | H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ |
1405 | | H5VL_map_args_t map_args; /* Arguments for map operations */ |
1406 | | herr_t ret_value = SUCCEED; /* Return value */ |
1407 | | |
1408 | | FUNC_ENTER_API(FAIL) |
1409 | | |
1410 | | /* Check arguments */ |
1411 | | if (key_mem_type_id < 0) |
1412 | | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID"); |
1413 | | |
1414 | | /* Get map pointer */ |
1415 | | if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) |
1416 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID"); |
1417 | | |
1418 | | /* Get the default dataset transfer property list if the user didn't provide one */ |
1419 | | if (H5P_DEFAULT == dxpl_id) |
1420 | | dxpl_id = H5P_DATASET_XFER_DEFAULT; |
1421 | | else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) |
1422 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); |
1423 | | |
1424 | | /* Set up VOL callback arguments */ |
1425 | | map_args.specific.specific_type = H5VL_MAP_DELETE; |
1426 | | map_args.specific.args.del.loc_params.type = H5VL_OBJECT_BY_SELF; |
1427 | | map_args.specific.args.del.loc_params.obj_type = H5I_get_type(map_id); |
1428 | | map_args.specific.args.del.key_mem_type_id = key_mem_type_id; |
1429 | | map_args.specific.args.del.key = key; |
1430 | | vol_cb_args.op_type = H5VL_MAP_SPECIFIC; |
1431 | | vol_cb_args.args = &map_args; |
1432 | | |
1433 | | /* Delete the key/value pair */ |
1434 | | if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) |
1435 | | HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to delete key/value pair"); |
1436 | | |
1437 | | done: |
1438 | | FUNC_LEAVE_API(ret_value) |
1439 | | } /* end H5Mdelete() */ |
1440 | | |
1441 | | #endif /* H5_HAVE_MAP_API */ |