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