Coverage Report

Created: 2024-06-18 06:29

/src/hdf5/src/H5A.c
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 "H5Amodule.h" /* This source code file is part of the H5A module */
18
19
/***********/
20
/* Headers */
21
/***********/
22
#include "H5private.h"   /* Generic Functions                        */
23
#include "H5Apkg.h"      /* Attributes                               */
24
#include "H5CXprivate.h" /* API Contexts                             */
25
#include "H5Eprivate.h"  /* Error handling                           */
26
#include "H5ESprivate.h" /* Event Sets                               */
27
#include "H5Iprivate.h"  /* IDs                                      */
28
#include "H5Sprivate.h"  /* Dataspace functions                      */
29
#include "H5VLprivate.h" /* Virtual Object Layer                     */
30
31
/****************/
32
/* Local Macros */
33
/****************/
34
35
/******************/
36
/* Local Typedefs */
37
/******************/
38
39
/********************/
40
/* Package Typedefs */
41
/********************/
42
43
/********************/
44
/* Local Prototypes */
45
/********************/
46
47
/* Helper routines for sync/async API calls */
48
static hid_t  H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
49
                                 hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
50
                                 void **token_ptr);
51
static hid_t  H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id,
52
                                     hid_t acpl_id, hid_t aapl_id, void **token_ptr,
53
                                     H5VL_object_t **_vol_obj_ptr);
54
static hid_t  H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name,
55
                                             hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
56
                                             hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
57
static hid_t  H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
58
                               hid_t aapl_id, void **token_ptr);
59
static hid_t  H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr,
60
                                   H5VL_object_t **_vol_obj_ptr);
61
static hid_t  H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name,
62
                                           hid_t aapl_id, hid_t lapl_id, void **token_ptr,
63
                                           H5VL_object_t **_vol_obj_ptr);
64
static hid_t  H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
65
                                          H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id,
66
                                          void **token_ptr, H5VL_object_t **_vol_obj_ptr);
67
static herr_t H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr,
68
                                    H5VL_object_t **_vol_obj_ptr);
69
static herr_t H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr,
70
                                   H5VL_object_t **_vol_obj_ptr);
71
static herr_t H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name,
72
                                 const char *new_name, void **token_ptr);
73
static herr_t H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name,
74
                                     void **token_ptr, H5VL_object_t **_vol_obj_ptr);
75
static herr_t H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_attr_name,
76
                                             const char *new_attr_name, hid_t lapl_id, void **token_ptr,
77
                                             H5VL_object_t **_vol_obj_ptr);
78
static herr_t H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
79
                                 bool *attr_exists, void **token_ptr);
80
static herr_t H5A__exists_api_common(hid_t obj_id, const char *attr_name, bool *attr_exists, void **token_ptr,
81
                                     H5VL_object_t **_vol_obj_ptr);
82
static herr_t H5A__exists_by_name_api_common(hid_t obj_id, const char *obj_name, const char *attr_name,
83
                                             bool *attr_exists, hid_t lapl_id, void **token_ptr,
84
                                             H5VL_object_t **_vol_obj_ptr);
85
86
/*********************/
87
/* Package Variables */
88
/*********************/
89
90
/*****************************/
91
/* Library Private Variables */
92
/*****************************/
93
94
/*******************/
95
/* Local Variables */
96
/*******************/
97
98
/*--------------------------------------------------------------------------
99
 * Function:    H5A__create_common
100
 *
101
 * Purpose:     This is the common function for creating HDF5 datasets.
102
 *
103
 * Return:      Success:    An attribute ID
104
 *              Failure:    H5I_INVALID_HID
105
 *
106
 *-------------------------------------------------------------------------
107
 */
108
static hid_t
109
H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
110
                   hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, void **token_ptr)
111
0
{
112
0
    void *attr      = NULL;            /* Attribute created */
113
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
114
115
0
    FUNC_ENTER_PACKAGE
116
117
    /* Sanity checks */
118
0
    assert(vol_obj);
119
0
    assert(loc_params);
120
0
    assert(attr_name);
121
122
    /* Create the attribute */
123
0
    if (NULL == (attr = H5VL_attr_create(vol_obj, loc_params, attr_name, type_id, space_id, acpl_id, aapl_id,
124
0
                                         H5P_DATASET_XFER_DEFAULT, token_ptr)))
125
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute");
126
127
    /* Register the new attribute and get an ID for it */
128
0
    if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, true)) < 0)
129
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID");
130
131
0
done:
132
    /* Cleanup on failure */
133
0
    if (H5I_INVALID_HID == ret_value)
134
0
        if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
135
0
            HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute");
136
137
0
    FUNC_LEAVE_NOAPI(ret_value)
138
0
} /* H5A__create_common() */
139
140
/*--------------------------------------------------------------------------
141
 * Function:    H5A__create_api_common
142
 *
143
 * Purpose:     This is the common function for creating HDF5 attributes
144
 *
145
 * Return:      Success:    An attribute ID
146
 *              Failure:    H5I_INVALID_HID
147
 *
148
 *-------------------------------------------------------------------------
149
 */
150
static hid_t
151
H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id,
152
                       hid_t aapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
153
0
{
154
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
155
0
    H5VL_object_t **vol_obj_ptr =
156
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
157
0
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
158
0
    hid_t             ret_value = H5I_INVALID_HID;    /* Return value */
159
160
0
    FUNC_ENTER_PACKAGE
161
162
    /* Check arguments */
163
0
    if (H5I_ATTR == H5I_get_type(loc_id))
164
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute");
165
0
    if (!attr_name)
166
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be NULL");
167
0
    if (!*attr_name)
168
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string");
169
170
    /* Set up object access arguments */
171
0
    if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, true, &aapl_id, vol_obj_ptr, &loc_params) < 0)
172
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments");
173
174
    /* Get correct property list */
175
0
    if (H5P_DEFAULT == acpl_id)
176
0
        acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
177
178
    /* Create the attribute */
179
0
    if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id,
180
0
                                        aapl_id, token_ptr)) < 0)
181
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute");
182
183
0
done:
184
0
    FUNC_LEAVE_NOAPI(ret_value)
185
0
} /* H5A__create_api_common() */
186
187
/*--------------------------------------------------------------------------
188
 * Function:    H5Acreate2
189
 *
190
 * Purpose:     Creates an attribute on an object
191
 *
192
 * Usage:
193
 *              hid_t H5Acreate2(loc_id, attr_name, type_id, space_id, acpl_id,
194
 *                  aapl_id)
195
 *
196
 * Description: This function creates an attribute that is attached to the
197
 *              object specified with 'loc_id'. The name specified with
198
 *              'attr_name' for each attribute for an object must be unique
199
 *              for that object. The 'type_id' and 'space_id' are created
200
 *              with the H5T and H5S interfaces, respectively. The 'aapl_id'
201
 *              property list is currently unused, but will be used in the
202
 *              future for optional attribute access properties. The
203
 *              attribute ID returned from this function must be released
204
 *              with H5Aclose or resource leaks will develop.
205
 *
206
 * Parameters:
207
 *              hid_t loc_id;           IN: Object (dataset or group) to be attached to
208
 *              const char *attr_name;  IN: Name of attribute to locate and open
209
 *              hid_t type_id;          IN: ID of datatype for attribute
210
 *              hid_t space_id;         IN: ID of dataspace for attribute
211
 *              hid_t acpl_id;          IN: ID of creation property list
212
 *              hid_t aapl_id;          IN: ID of Attribute access property list (currently not used)
213
 *
214
 * Return:      Success:    An ID for the created attribute
215
 *
216
 *              Failure:    H5I_INVALID_HID
217
 *
218
 *-------------------------------------------------------------------------
219
 */
220
hid_t
221
H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id)
222
0
{
223
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
224
225
0
    FUNC_ENTER_API(H5I_INVALID_HID)
226
227
    /* Create the attribute synchronously */
228
0
    if ((ret_value =
229
0
             H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, NULL, NULL)) < 0)
230
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute");
231
232
0
done:
233
0
    FUNC_LEAVE_API(ret_value)
234
0
} /* H5Acreate2() */
235
236
/*--------------------------------------------------------------------------
237
 * Function:    H5Acreate_sync
238
 *
239
 * Purpose:     Asynchronous version of H5Acreate
240
 *
241
 * Return:      Success:    An attribute ID
242
 *              Failure:    H5I_INVALID_HID
243
 *
244
 *-------------------------------------------------------------------------
245
 */
246
hid_t
247
H5Acreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
248
                const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
249
                hid_t es_id)
250
0
{
251
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
252
0
    void          *token     = NULL;            /* Request token for async operation        */
253
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
254
0
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
255
256
0
    FUNC_ENTER_API(H5I_INVALID_HID)
257
258
    /* Set up request token pointer for asynchronous operation */
259
0
    if (H5ES_NONE != es_id)
260
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
261
262
    /* Create the attribute asynchronously */
263
0
    if ((ret_value = H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, token_ptr,
264
0
                                            &vol_obj)) < 0)
265
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute");
266
267
    /* If a token was created, add the token to the event set */
268
0
    if (NULL != token)
269
        /* clang-format off */
270
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
271
0
                        H5ARG_TRACE10(__func__, "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, es_id)) < 0) {
272
            /* clang-format on */
273
0
            if (H5I_dec_app_ref(ret_value) < 0)
274
0
                HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID");
275
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
276
0
        } /* end if */
277
278
0
done:
279
0
    FUNC_LEAVE_API(ret_value)
280
0
} /* H5Acreate_async() */
281
282
/*--------------------------------------------------------------------------
283
 * Function:    H5A__create_by_name_api_common
284
 *
285
 * Purpose:     This is the common function for creating HDF5 attributes by name
286
 *
287
 * Return:      Success:    An attribute ID
288
 *              Failure:    H5I_INVALID_HID
289
 *
290
 *-------------------------------------------------------------------------
291
 */
292
static hid_t
293
H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id,
294
                               hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, void **token_ptr,
295
                               H5VL_object_t **_vol_obj_ptr)
296
0
{
297
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
298
0
    H5VL_object_t **vol_obj_ptr =
299
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
300
0
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
301
0
    hid_t             ret_value = H5I_INVALID_HID;    /* Return value */
302
303
0
    FUNC_ENTER_PACKAGE
304
305
    /* Check arguments */
306
0
    if (H5I_ATTR == H5I_get_type(loc_id))
307
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute");
308
0
    if (!attr_name)
309
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be NULL");
310
0
    if (!*attr_name)
311
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string");
312
313
    /* obj_name is verified in H5VL_setup_name_args() */
314
    /* Set up object access arguments */
315
0
    if (H5VL_setup_name_args(loc_id, obj_name, true, lapl_id, vol_obj_ptr, &loc_params) < 0)
316
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments");
317
318
    /* Verify access property list and set up collective metadata if appropriate */
319
0
    if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, true) < 0)
320
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info");
321
322
    /* Get correct property list */
323
0
    if (H5P_DEFAULT == acpl_id)
324
0
        acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
325
326
    /* Create the attribute */
327
0
    if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id,
328
0
                                        aapl_id, token_ptr)) < 0)
329
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute");
330
331
0
done:
332
0
    FUNC_LEAVE_NOAPI(ret_value)
333
0
} /* H5A__create_by_name_api_common() */
334
335
/*--------------------------------------------------------------------------
336
 NAME
337
    H5Acreate_by_name
338
 PURPOSE
339
    Creates an attribute on an object
340
 USAGE
341
    hid_t H5Acreate_by_name(loc_id, obj_name, attr_name, type_id, space_id, acpl_id,
342
            aapl_id, lapl_id)
343
        hid_t loc_id;       IN: Object (dataset or group) to be attached to
344
        const char *obj_name;   IN: Name of object relative to location
345
        const char *attr_name;  IN: Name of attribute to locate and open
346
        hid_t type_id;          IN: ID of datatype for attribute
347
        hid_t space_id;         IN: ID of dataspace for attribute
348
        hid_t acpl_id;          IN: ID of creation property list
349
        hid_t aapl_id;          IN: ID of Attribute access property list (currently not used)
350
        hid_t lapl_id;          IN: Link access property list
351
 RETURNS
352
    Non-negative on success/H5I_INVALID_HID on failure
353
354
 DESCRIPTION
355
        This function creates an attribute that is attached to the object
356
    specified with 'loc_id/obj_name'.  The name specified with 'attr_name' for
357
    each attribute for an object must be unique for that object.  The 'type_id'
358
    and 'space_id' are created with the H5T and H5S interfaces respectively.
359
    The 'aapl_id' property list is currently unused, but will be used in the
360
    future for optional attribute access properties.  The attribute ID returned
361
    from this function must be released with H5Aclose or resource leaks will
362
    develop.
363
364
--------------------------------------------------------------------------*/
365
hid_t
366
H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id,
367
                  hid_t acpl_id, hid_t aapl_id, hid_t lapl_id)
368
0
{
369
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
370
371
0
    FUNC_ENTER_API(H5I_INVALID_HID)
372
373
    /* Create the attribute synchronously */
374
0
    if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id,
375
0
                                                    aapl_id, lapl_id, NULL, NULL)) < 0)
376
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute");
377
378
0
done:
379
0
    FUNC_LEAVE_API(ret_value)
380
0
} /* H5Acreate_by_name() */
381
382
/*--------------------------------------------------------------------------
383
 * Function:    H5Acreate_by_name_async
384
 *
385
 * Purpose:     Asynchronous version of H5Acreate_by_name
386
 *
387
 * Return:      Success:    An attribute ID
388
 *              Failure:    H5I_INVALID_HID
389
 *
390
 *-------------------------------------------------------------------------
391
 */
392
hid_t
393
H5Acreate_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
394
                        const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id,
395
                        hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, hid_t es_id)
396
0
{
397
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
398
0
    void          *token     = NULL;            /* Request token for async operation        */
399
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
400
0
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
401
402
0
    FUNC_ENTER_API(H5I_INVALID_HID)
403
404
    /* Set up request token pointer for asynchronous operation */
405
0
    if (H5ES_NONE != es_id)
406
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
407
408
    /* Create the attribute asynchronously */
409
0
    if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id,
410
0
                                                    aapl_id, lapl_id, token_ptr, &vol_obj)) < 0)
411
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute");
412
413
    /* If a token was created, add the token to the event set */
414
0
    if (NULL != token)
415
        /* clang-format off */
416
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
417
0
                        H5ARG_TRACE12(__func__, "*s*sIui*s*siiiiii", app_file, app_func, app_line, loc_id, obj_name, attr_name, type_id, space_id, acpl_id, aapl_id, lapl_id, es_id)) < 0) {
418
            /* clang-format on */
419
0
            if (H5I_dec_app_ref(ret_value) < 0)
420
0
                HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID");
421
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
422
0
        } /* end if */
423
424
0
done:
425
0
    FUNC_LEAVE_API(ret_value)
426
0
} /* H5Acreate_by_name_async() */
427
428
/*-------------------------------------------------------------------------
429
 * Function:    H5A__open_common
430
 *
431
 * Purpose:     This is the common function for opening an attribute
432
 *
433
 * Return:      Success:    A group ID
434
 *              Failure:    H5I_INVALID_HID
435
 *
436
 *-------------------------------------------------------------------------
437
 */
438
static hid_t
439
H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, hid_t aapl_id,
440
                 void **token_ptr)
441
78
{
442
78
    void *attr      = NULL; /* attr object from VOL connector */
443
78
    hid_t ret_value = H5I_INVALID_HID;
444
445
78
    FUNC_ENTER_PACKAGE
446
447
    /* Sanity checks */
448
78
    assert(vol_obj);
449
78
    assert(loc_params);
450
451
    /* Open the attribute */
452
78
    if (NULL ==
453
78
        (attr = H5VL_attr_open(vol_obj, loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr)))
454
14
        HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name);
455
456
    /* Register the attribute and get an ID for it */
457
64
    if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, true)) < 0)
458
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID");
459
460
78
done:
461
    /* Cleanup on failure */
462
78
    if (H5I_INVALID_HID == ret_value)
463
14
        if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
464
0
            HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute");
465
466
78
    FUNC_LEAVE_NOAPI(ret_value)
467
64
} /* H5A__open_common() */
468
469
/*-------------------------------------------------------------------------
470
 * Function:    H5A__open_api_common
471
 *
472
 * Purpose:     This is the common function for opening an attribute
473
 *
474
 * Return:      Success:    A group ID
475
 *              Failure:    H5I_INVALID_HID
476
 *
477
 *-------------------------------------------------------------------------
478
 */
479
static hid_t
480
H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr,
481
                     H5VL_object_t **_vol_obj_ptr)
482
0
{
483
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
484
0
    H5VL_object_t **vol_obj_ptr =
485
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
486
0
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
487
0
    hid_t             ret_value = H5I_INVALID_HID;    /* Return value */
488
489
0
    FUNC_ENTER_PACKAGE
490
491
    /* Check arguments */
492
0
    if (H5I_ATTR == H5I_get_type(loc_id))
493
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute");
494
0
    if (!attr_name)
495
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL");
496
0
    if (!*attr_name)
497
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string");
498
499
    /* Set up object access arguments */
500
0
    if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, false, &aapl_id, vol_obj_ptr, &loc_params) < 0)
501
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments");
502
503
    /* Open the attribute */
504
0
    if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0)
505
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name);
506
507
0
done:
508
0
    FUNC_LEAVE_NOAPI(ret_value)
509
0
} /* H5A__open_api_common() */
510
511
/*--------------------------------------------------------------------------
512
 NAME
513
    H5Aopen
514
 PURPOSE
515
    Opens an attribute for an object by looking up the attribute name
516
 USAGE
517
    hid_t H5Aopen(loc_id, attr_name, aapl_id)
518
        hid_t loc_id;           IN: Object that attribute is attached to
519
        const char *attr_name;  IN: Name of attribute to locate and open
520
        hid_t aapl_id;          IN: Attribute access property list
521
 RETURNS
522
    ID of attribute on success, H5I_INVALID_HID on failure
523
524
 DESCRIPTION
525
        This function opens an existing attribute for access.  The attribute
526
    name specified is used to look up the corresponding attribute for the
527
    object.  The attribute ID returned from this function must be released with
528
    H5Aclose or resource leaks will develop.
529
--------------------------------------------------------------------------*/
530
hid_t
531
H5Aopen(hid_t loc_id, const char *attr_name, hid_t aapl_id)
532
0
{
533
0
    hid_t ret_value = H5I_INVALID_HID;
534
535
0
    FUNC_ENTER_API(H5I_INVALID_HID)
536
537
    /* Open the attribute synchronously */
538
0
    if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, NULL, NULL)) < 0)
539
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute");
540
541
0
done:
542
0
    FUNC_LEAVE_API(ret_value)
543
0
} /* H5Aopen() */
544
545
/*--------------------------------------------------------------------------
546
 *  NAME
547
 *      H5Aopen_async
548
 *  PURPOSE
549
 *      Asynchronous version of H5Aopen
550
 *
551
 *  RETURNS
552
 *      ID of attribute on success, H5I_INVALID_HID on failure
553
 *
554
 *--------------------------------------------------------------------------*/
555
hid_t
556
H5Aopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
557
              const char *attr_name, hid_t aapl_id, hid_t es_id)
558
0
{
559
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
560
0
    void          *token     = NULL;            /* Request token for async operation        */
561
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
562
0
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
563
564
0
    FUNC_ENTER_API(H5I_INVALID_HID)
565
566
    /* Set up request token pointer for asynchronous operation */
567
0
    if (H5ES_NONE != es_id)
568
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
569
570
    /* Open the attribute asynchronously */
571
0
    if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, token_ptr, &vol_obj)) < 0)
572
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute");
573
574
    /* If a token was created, add the token to the event set */
575
0
    if (NULL != token)
576
        /* clang-format off */
577
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
578
0
                        H5ARG_TRACE7(__func__, "*s*sIui*sii", app_file, app_func, app_line, loc_id, attr_name, aapl_id, es_id)) < 0) {
579
            /* clang-format on */
580
0
            if (H5I_dec_app_ref(ret_value) < 0)
581
0
                HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID");
582
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
583
0
        } /* end if */
584
585
0
done:
586
0
    FUNC_LEAVE_API(ret_value)
587
0
} /* H5Aopen_async() */
588
589
/*-------------------------------------------------------------------------
590
 * Function:    H5A__open_by_name_api_common
591
 *
592
 * Purpose:     This is the common function for opening an attribute
593
 *
594
 * Return:      Success:    A group ID
595
 *              Failure:    H5I_INVALID_HID
596
 *
597
 *-------------------------------------------------------------------------
598
 */
599
static hid_t
600
H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id,
601
                             hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
602
81
{
603
81
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
604
81
    H5VL_object_t **vol_obj_ptr =
605
81
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
606
81
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
607
81
    hid_t             ret_value = H5I_INVALID_HID;
608
609
81
    FUNC_ENTER_PACKAGE
610
611
    /* Check arguments */
612
81
    if (H5I_ATTR == H5I_get_type(loc_id))
613
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute");
614
615
81
    if (!attr_name || !*attr_name)
616
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name");
617
618
    /* obj_name is verified in H5VL_setup_name_args() */
619
    /* Set up object access arguments */
620
81
    if (H5VL_setup_name_args(loc_id, obj_name, false, lapl_id, vol_obj_ptr, &loc_params) < 0)
621
3
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments");
622
623
    /* Verify access property list and set up collective metadata if appropriate */
624
78
    if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, false) < 0)
625
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info");
626
627
    /* Open the attribute */
628
78
    if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0)
629
14
        HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name);
630
631
81
done:
632
81
    FUNC_LEAVE_NOAPI(ret_value)
633
78
} /* H5A__open_by_name_api_common() */
634
635
/*--------------------------------------------------------------------------
636
 NAME
637
    H5Aopen_by_name
638
 PURPOSE
639
    Opens an attribute for an object by looking up the attribute name
640
 USAGE
641
    hid_t H5Aopen_by_name(loc_id, obj_name, attr_name, aapl_id, lapl_id)
642
        hid_t loc_id;           IN: Object that attribute is attached to
643
        const char *obj_name;   IN: Name of the object relative to location
644
        const char *attr_name;  IN: Name of attribute to locate and open
645
        hid_t aapl_id;          IN: Attribute access property list
646
        hid_t lapl_id;          IN: Link access property list
647
 RETURNS
648
    ID of attribute on success, H5I_INVALID_HID on failure
649
650
 DESCRIPTION
651
        This function opens an existing attribute for access.  The attribute
652
    name specified is used to look up the corresponding attribute for the
653
    object.  The attribute ID returned from this function must be released with
654
    H5Aclose or resource leaks will develop.
655
--------------------------------------------------------------------------*/
656
hid_t
657
H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id)
658
81
{
659
81
    hid_t ret_value = H5I_INVALID_HID;
660
661
162
    FUNC_ENTER_API(H5I_INVALID_HID)
662
663
    /* Open the attribute by name asynchronously */
664
162
    if ((ret_value =
665
81
             H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, NULL, NULL)) < 0)
666
17
        HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open attribute");
667
668
81
done:
669
81
    FUNC_LEAVE_API(ret_value)
670
162
} /* end H5Aopen_by_name() */
671
672
/*--------------------------------------------------------------------------
673
 *  NAME
674
 *      H5Aopen_by_name_async
675
 *  PURPOSE
676
 *      Asynchronous version of H5Aopen_by_name
677
 *
678
 *  RETURNS
679
 *      ID of attribute on success, H5I_INVALID_HID on failure
680
 *
681
 *--------------------------------------------------------------------------*/
682
hid_t
683
H5Aopen_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
684
                      const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id, hid_t es_id)
685
0
{
686
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
687
0
    void          *token     = NULL;            /* Request token for async operation        */
688
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
689
0
    hid_t          ret_value = H5I_INVALID_HID;
690
691
0
    FUNC_ENTER_API(H5I_INVALID_HID)
692
693
    /* Set up request token pointer for asynchronous operation */
694
0
    if (H5ES_NONE != es_id)
695
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
696
697
    /* Open the attribute by name asynchronously */
698
0
    if ((ret_value = H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, token_ptr,
699
0
                                                  &vol_obj)) < 0)
700
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open attribute");
701
702
    /* If a token was created, add the token to the event set */
703
0
    if (NULL != token)
704
        /* clang-format off */
705
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
706
0
                        H5ARG_TRACE9(__func__, "*s*sIui*s*siii", app_file, app_func, app_line, loc_id, obj_name, attr_name, aapl_id, lapl_id, es_id)) < 0) {
707
            /* clang-format on */
708
0
            if (H5I_dec_app_ref(ret_value) < 0)
709
0
                HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID");
710
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
711
0
        } /* end if */
712
713
0
done:
714
0
    FUNC_LEAVE_API(ret_value)
715
0
} /* end H5Aopen_by_name_async() */
716
717
/*-------------------------------------------------------------------------
718
 * Function:    H5A__open_by_idx_api_common
719
 *
720
 * Purpose:     This is the common function for opening an attribute
721
 *
722
 * Return:      Success:    A group ID
723
 *              Failure:    H5I_INVALID_HID
724
 *
725
 *-------------------------------------------------------------------------
726
 */
727
static hid_t
728
H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order,
729
                            hsize_t n, hid_t aapl_id, hid_t lapl_id, void **token_ptr,
730
                            H5VL_object_t **_vol_obj_ptr)
731
0
{
732
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
733
0
    H5VL_object_t **vol_obj_ptr =
734
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
735
0
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
736
0
    hid_t             ret_value = H5I_INVALID_HID;
737
738
0
    FUNC_ENTER_PACKAGE
739
740
    /* Check arguments */
741
0
    if (H5I_ATTR == H5I_get_type(loc_id))
742
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute");
743
0
    if (!obj_name || !*obj_name)
744
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name");
745
0
    if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
746
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified");
747
0
    if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
748
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified");
749
750
    /* Set up object access arguments */
751
0
    if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, false, lapl_id, vol_obj_ptr, &loc_params) <
752
0
        0)
753
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments");
754
755
    /* Verify access property list and set up collective metadata if appropriate */
756
0
    if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, false) < 0)
757
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info");
758
759
    /* Open the attribute */
760
0
    if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, NULL, aapl_id, token_ptr)) < 0)
761
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute");
762
763
0
done:
764
0
    FUNC_LEAVE_NOAPI(ret_value)
765
0
} /* H5A__open_by_idx_api_common() */
766
767
/*--------------------------------------------------------------------------
768
 NAME
769
    H5Aopen_by_idx
770
 PURPOSE
771
    Opens the n'th attribute for an object, according to the order within
772
    an index
773
 USAGE
774
    hid_t H5Aopen_by_idx(loc_id, obj_ame, idx_type, order, n, aapl_id, lapl_id)
775
        hid_t loc_id;           IN: Object that attribute is attached to
776
        const char *obj_name;   IN: Name of the object relative to location
777
        H5_index_t idx_type;    IN: Type of index to use
778
        H5_iter_order_t order;  IN: Order to iterate over index
779
        hsize_t n;              IN: Index (0-based) attribute to open
780
        hid_t aapl_id;          IN: Attribute access property list
781
        hid_t lapl_id;          IN: Link access property list
782
 RETURNS
783
    ID of attribute on success, H5I_INVALID_HID on failure
784
785
 DESCRIPTION
786
        This function opens an existing attribute for access.  The attribute
787
    index specified is used to look up the corresponding attribute for the
788
    object.  The attribute ID returned from this function must be released with
789
    H5Aclose or resource leaks will develop.
790
--------------------------------------------------------------------------*/
791
hid_t
792
H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
793
               hid_t aapl_id, hid_t lapl_id)
794
0
{
795
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
796
797
0
    FUNC_ENTER_API(H5I_INVALID_HID)
798
799
    /* Open the attribute by idx synchronously */
800
0
    if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, NULL,
801
0
                                                 NULL)) < 0)
802
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute");
803
804
0
done:
805
0
    FUNC_LEAVE_API(ret_value)
806
0
} /* H5Aopen_by_idx() */
807
808
/*--------------------------------------------------------------------------
809
 *  NAME
810
 *      H5Aopen_by_idx_async
811
 *  PURPOSE
812
 *      Asynchronous version of H5Aopen_by_idx
813
 *
814
 *  RETURNS
815
 *      ID of attribute on success, H5I_INVALID_HID on failure
816
 *
817
 *--------------------------------------------------------------------------*/
818
hid_t
819
H5Aopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
820
                     const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
821
                     hid_t aapl_id, hid_t lapl_id, hid_t es_id)
822
0
{
823
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
824
0
    void          *token     = NULL;            /* Request token for async operation        */
825
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
826
0
    hid_t          ret_value = H5I_INVALID_HID;
827
828
0
    FUNC_ENTER_API(H5I_INVALID_HID)
829
830
    /* Set up request token pointer for asynchronous operation */
831
0
    if (H5ES_NONE != es_id)
832
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
833
834
    /* Open the attribute by idx asynchronously */
835
0
    if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id,
836
0
                                                 token_ptr, &vol_obj)) < 0)
837
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute");
838
839
    /* If a token was created, add the token to the event set */
840
0
    if (NULL != token)
841
        /* clang-format off */
842
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
843
0
                        H5ARG_TRACE11(__func__, "*s*sIui*sIiIohiii", app_file, app_func, app_line, loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, es_id)) < 0) {
844
            /* clang-format on */
845
0
            if (H5I_dec_app_ref(ret_value) < 0)
846
0
                HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID");
847
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
848
0
        } /* end if */
849
850
0
done:
851
0
    FUNC_LEAVE_API(ret_value)
852
0
} /* end H5Aopen_by_idx_async() */
853
854
/*--------------------------------------------------------------------------
855
 NAME
856
    H5A__write_api_common
857
 PURPOSE
858
    Common helper routine for sync/async dataset write operations.
859
 RETURNS
860
    Non-negative on success/Negative on failure
861
--------------------------------------------------------------------------*/
862
static herr_t
863
H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr,
864
                      H5VL_object_t **_vol_obj_ptr)
865
0
{
866
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
867
0
    H5VL_object_t **vol_obj_ptr =
868
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
869
0
    herr_t ret_value = SUCCEED;                       /* Return value */
870
871
0
    FUNC_ENTER_PACKAGE
872
873
    /* Check arguments */
874
0
    if (H5I_DATATYPE != H5I_get_type(type_id))
875
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
876
0
    if (NULL == buf)
877
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL");
878
879
    /* Get attribute pointer */
880
0
    if (H5VL_setup_args(attr_id, H5I_ATTR, vol_obj_ptr) < 0)
881
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute");
882
883
    /* Write the attribute data */
884
0
    if (H5VL_attr_write(*vol_obj_ptr, type_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
885
0
        HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute");
886
887
0
done:
888
0
    FUNC_LEAVE_NOAPI(ret_value)
889
0
} /* H5A__write_api_common() */
890
891
/*--------------------------------------------------------------------------
892
 NAME
893
    H5Awrite
894
 PURPOSE
895
    Write out data to an attribute
896
 USAGE
897
    herr_t H5Awrite (attr_id, dtype_id, buf)
898
        hid_t attr_id;       IN: Attribute to write
899
        hid_t dtype_id;       IN: Memory datatype of buffer
900
        const void *buf;     IN: Buffer of data to write
901
 RETURNS
902
    Non-negative on success/Negative on failure
903
904
 DESCRIPTION
905
        This function writes a complete attribute to disk.
906
--------------------------------------------------------------------------*/
907
herr_t
908
H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf)
909
0
{
910
0
    herr_t ret_value = SUCCEED; /* Return value */
911
912
0
    FUNC_ENTER_API(FAIL)
913
914
    /* Synchronously write the data */
915
0
    if (H5A__write_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0)
916
0
        HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't synchronously write data");
917
918
0
done:
919
0
    FUNC_LEAVE_API(ret_value)
920
0
} /* H5Awrite() */
921
922
/*--------------------------------------------------------------------------
923
 NAME
924
    H5Awrite_async
925
 PURPOSE
926
    Asynchronous version of H5Awrite
927
 RETURNS
928
    Non-negative on success/Negative on failure
929
--------------------------------------------------------------------------*/
930
herr_t
931
H5Awrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id,
932
               const void *buf, hid_t es_id)
933
0
{
934
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for attr_id */
935
0
    void          *token     = NULL;            /* Request token for async operation        */
936
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
937
0
    herr_t         ret_value = SUCCEED;         /* Return value */
938
939
0
    FUNC_ENTER_API(FAIL)
940
941
    /* Set up request token pointer for asynchronous operation */
942
0
    if (H5ES_NONE != es_id)
943
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
944
945
    /* Asynchronously write the data */
946
0
    if (H5A__write_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0)
947
0
        HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't asynchronously write data");
948
949
    /* If a token was created, add the token to the event set */
950
0
    if (NULL != token)
951
        /* clang-format off */
952
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
953
0
                        H5ARG_TRACE7(__func__, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0)
954
            /* clang-format on */
955
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set");
956
957
0
done:
958
0
    FUNC_LEAVE_API(ret_value)
959
0
} /* H5Awrite_async() */
960
961
/*--------------------------------------------------------------------------
962
 *  NAME
963
 *       H5A__read_api_common
964
 *  PURPOSE
965
 *      Common helper routine for sync/async attribute read operations.
966
 *  RETURNS
967
 *      Non-negative on success/Negative on failure
968
 *--------------------------------------------------------------------------*/
969
static herr_t
970
H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
971
76
{
972
76
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
973
76
    H5VL_object_t **vol_obj_ptr =
974
76
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
975
76
    herr_t ret_value = SUCCEED;                       /* Return value */
976
977
76
    FUNC_ENTER_PACKAGE
978
979
    /* Check arguments */
980
76
    if (H5I_DATATYPE != H5I_get_type(dtype_id))
981
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
982
76
    if (NULL == buf)
983
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL");
984
985
    /* Get attribute object pointer */
986
76
    if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
987
12
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute");
988
989
    /* Read the attribute data */
990
64
    if (H5VL_attr_read(*vol_obj_ptr, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
991
3
        HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute");
992
993
76
done:
994
76
    FUNC_LEAVE_NOAPI(ret_value)
995
64
} /* H5A__read_api_common() */
996
997
/*--------------------------------------------------------------------------
998
 NAME
999
    H5Aread
1000
 PURPOSE
1001
    Read in data from an attribute
1002
 USAGE
1003
    herr_t H5Aread (attr_id, dtype_id, buf)
1004
        hid_t attr_id;       IN: Attribute to read
1005
        hid_t dtype_id;       IN: Memory datatype of buffer
1006
        void *buf;           IN: Buffer for data to read
1007
 RETURNS
1008
    Non-negative on success/Negative on failure
1009
1010
 DESCRIPTION
1011
        This function reads a complete attribute from disk.
1012
--------------------------------------------------------------------------*/
1013
herr_t
1014
H5Aread(hid_t attr_id, hid_t dtype_id, void *buf /*out*/)
1015
76
{
1016
76
    herr_t ret_value = SUCCEED; /* Return value */
1017
1018
152
    FUNC_ENTER_API(FAIL)
1019
1020
    /* Synchronously read the data */
1021
152
    if (H5A__read_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0)
1022
15
        HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't synchronously read data");
1023
1024
76
done:
1025
76
    FUNC_LEAVE_API(ret_value)
1026
152
} /* H5Aread() */
1027
1028
/*--------------------------------------------------------------------------
1029
 *  NAME
1030
 *      H5Aread_async
1031
 *  PURPOSE
1032
 *      Asynchronous version of H5Aread
1033
 *  RETURNS
1034
 *      Non-negative on success/Negative on failure
1035
 *--------------------------------------------------------------------------*/
1036
herr_t
1037
H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id,
1038
              void *buf /*out*/, hid_t es_id)
1039
0
{
1040
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for attr_id */
1041
0
    void          *token     = NULL;            /* Request token for async operation        */
1042
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1043
0
    herr_t         ret_value = SUCCEED;         /* Return value */
1044
1045
0
    FUNC_ENTER_API(FAIL)
1046
1047
    /* Set up request token pointer for asynchronous operation */
1048
0
    if (H5ES_NONE != es_id)
1049
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
1050
1051
    /* Asynchronously read the data */
1052
0
    if (H5A__read_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0)
1053
0
        HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't asynchronously read data");
1054
1055
    /* If a token was created, add the token to the event set */
1056
0
    if (NULL != token)
1057
        /* clang-format off */
1058
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
1059
0
                        H5ARG_TRACE7(__func__, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0)
1060
            /* clang-format on */
1061
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1062
1063
0
done:
1064
0
    FUNC_LEAVE_API(ret_value)
1065
0
} /* H5Aread_async() */
1066
1067
/*--------------------------------------------------------------------------
1068
 NAME
1069
    H5Aget_space
1070
 PURPOSE
1071
    Gets a copy of the dataspace for an attribute
1072
 USAGE
1073
    hid_t H5Aget_space (attr_id)
1074
        hid_t attr_id;       IN: Attribute to get dataspace of
1075
 RETURNS
1076
    A dataspace ID on success, H5I_INVALID_HID on failure
1077
1078
 DESCRIPTION
1079
        This function retrieves a copy of the dataspace for an attribute.
1080
    The dataspace ID returned from this function must be released with H5Sclose
1081
    or resource leaks will develop.
1082
--------------------------------------------------------------------------*/
1083
hid_t
1084
H5Aget_space(hid_t attr_id)
1085
3
{
1086
3
    H5VL_object_t       *vol_obj = NULL;              /* Attribute object for ID */
1087
3
    H5VL_attr_get_args_t vol_cb_args;                 /* Arguments to VOL callback */
1088
3
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
1089
1090
6
    FUNC_ENTER_API(H5I_INVALID_HID)
1091
1092
    /* Check arguments */
1093
6
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1094
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute");
1095
1096
    /* Set up VOL callback arguments */
1097
3
    vol_cb_args.op_type                 = H5VL_ATTR_GET_SPACE;
1098
3
    vol_cb_args.args.get_space.space_id = H5I_INVALID_HID;
1099
1100
    /* Get the dataspace */
1101
3
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1102
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace of attribute");
1103
1104
    /* Set the return value */
1105
3
    ret_value = vol_cb_args.args.get_space.space_id;
1106
1107
3
done:
1108
3
    FUNC_LEAVE_API(ret_value)
1109
3
} /* H5Aget_space() */
1110
1111
/*--------------------------------------------------------------------------
1112
 NAME
1113
    H5Aget_type
1114
 PURPOSE
1115
    Gets a copy of the datatype for an attribute
1116
 USAGE
1117
    hid_t H5Aget_type (attr_id)
1118
        hid_t attr_id;       IN: Attribute to get datatype of
1119
 RETURNS
1120
    A datatype ID on success, H5I_INVALID_HID on failure
1121
1122
 DESCRIPTION
1123
        This function retrieves a copy of the datatype for an attribute.
1124
    The datatype ID returned from this function must be released with H5Tclose
1125
    or resource leaks will develop.
1126
--------------------------------------------------------------------------*/
1127
hid_t
1128
H5Aget_type(hid_t attr_id)
1129
58
{
1130
58
    H5VL_object_t       *vol_obj = NULL;              /* Attribute object for ID */
1131
58
    H5VL_attr_get_args_t vol_cb_args;                 /* Arguments to VOL callback */
1132
58
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
1133
1134
116
    FUNC_ENTER_API(H5I_INVALID_HID)
1135
1136
    /* Check arguments */
1137
116
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1138
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute");
1139
1140
    /* Set up VOL callback arguments */
1141
58
    vol_cb_args.op_type               = H5VL_ATTR_GET_TYPE;
1142
58
    vol_cb_args.args.get_type.type_id = H5I_INVALID_HID;
1143
1144
    /* Get the datatype */
1145
58
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1146
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype of attribute");
1147
1148
    /* Set the return value */
1149
58
    ret_value = vol_cb_args.args.get_type.type_id;
1150
1151
58
done:
1152
58
    FUNC_LEAVE_API(ret_value)
1153
58
} /* H5Aget_type() */
1154
1155
/*--------------------------------------------------------------------------
1156
 NAME
1157
    H5Aget_create_plist
1158
 PURPOSE
1159
    Gets a copy of the creation property list for an attribute
1160
 USAGE
1161
    hssize_t H5Aget_create_plist (attr_id, buf_size, buf)
1162
        hid_t attr_id;      IN: Attribute to get the name of
1163
 RETURNS
1164
    This function returns the ID of a copy of the attribute's creation
1165
    property list, or H5I_INVALID_HID on failure.
1166
1167
 ERRORS
1168
1169
 DESCRIPTION
1170
        This function returns a copy of the creation property list for
1171
    an attribute.  The resulting ID must be closed with H5Pclose() or
1172
    resource leaks will occur.
1173
--------------------------------------------------------------------------*/
1174
hid_t
1175
H5Aget_create_plist(hid_t attr_id)
1176
0
{
1177
0
    H5VL_object_t       *vol_obj = NULL;              /* Attribute object for ID */
1178
0
    H5VL_attr_get_args_t vol_cb_args;                 /* Arguments to VOL callback */
1179
0
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
1180
1181
0
    FUNC_ENTER_API(H5I_INVALID_HID)
1182
1183
0
    assert(H5P_LST_ATTRIBUTE_CREATE_ID_g != -1);
1184
1185
    /* Check arguments */
1186
0
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1187
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute");
1188
1189
    /* Set up VOL callback arguments */
1190
0
    vol_cb_args.op_type               = H5VL_ATTR_GET_ACPL;
1191
0
    vol_cb_args.args.get_acpl.acpl_id = H5I_INVALID_HID;
1192
1193
    /* Get the acpl */
1194
0
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1195
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID,
1196
0
                    "unable to get creation property list for attribute");
1197
1198
    /* Set the return value */
1199
0
    ret_value = vol_cb_args.args.get_acpl.acpl_id;
1200
1201
0
done:
1202
0
    FUNC_LEAVE_API(ret_value)
1203
0
} /* end H5Aget_create_plist() */
1204
1205
/*--------------------------------------------------------------------------
1206
 NAME
1207
    H5Aget_name
1208
 PURPOSE
1209
    Gets a copy of the name for an attribute
1210
 USAGE
1211
    hssize_t H5Aget_name (attr_id, buf_size, buf)
1212
        hid_t attr_id;      IN: Attribute to get the name of
1213
        size_t buf_size;    IN: The size of the buffer to store the string in.
1214
        char *buf;          IN: Buffer to store name in
1215
 RETURNS
1216
    This function returns the length of the attribute's name (which may be
1217
    longer than 'buf_size') on success or negative for failure.
1218
1219
 DESCRIPTION
1220
        This function retrieves the name of an attribute for an attribute ID.
1221
    Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string
1222
    terminator.  If the name of the attribute is longer than 'buf_size'-1,
1223
    the string terminator is stored in the last position of the buffer to
1224
    properly terminate the string.
1225
--------------------------------------------------------------------------*/
1226
ssize_t
1227
H5Aget_name(hid_t attr_id, size_t buf_size, char *buf /*out*/)
1228
0
{
1229
0
    H5VL_object_t       *vol_obj = NULL;     /* Attribute object for ID */
1230
0
    H5VL_attr_get_args_t vol_cb_args;        /* Arguments to VOL callback */
1231
0
    size_t               attr_name_len = 0;  /* Length of attribute name */
1232
0
    ssize_t              ret_value     = -1; /* Return value */
1233
1234
0
    FUNC_ENTER_API((-1))
1235
1236
    /* check arguments */
1237
0
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1238
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not an attribute");
1239
0
    if (!buf && buf_size)
1240
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "buf cannot be NULL if buf_size is non-zero");
1241
1242
    /* Set up VOL callback arguments */
1243
0
    vol_cb_args.op_type                           = H5VL_ATTR_GET_NAME;
1244
0
    vol_cb_args.args.get_name.loc_params.type     = H5VL_OBJECT_BY_SELF;
1245
0
    vol_cb_args.args.get_name.loc_params.obj_type = H5I_get_type(attr_id);
1246
0
    vol_cb_args.args.get_name.buf_size            = buf_size;
1247
0
    vol_cb_args.args.get_name.buf                 = buf;
1248
0
    vol_cb_args.args.get_name.attr_name_len       = &attr_name_len;
1249
1250
    /* Get the attribute name */
1251
0
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1252
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, (-1), "unable to get attribute name");
1253
1254
    /* Set the return value */
1255
0
    ret_value = (ssize_t)attr_name_len;
1256
1257
0
done:
1258
0
    FUNC_LEAVE_API(ret_value)
1259
0
} /* H5Aget_name() */
1260
1261
/*-------------------------------------------------------------------------
1262
 * Function:  H5Aget_name_by_idx
1263
 *
1264
 * Purpose: Retrieve the name of an attribute, according to the
1265
 *    order within an index.
1266
 *
1267
 *              Same pattern of behavior as H5Iget_name.
1268
 *
1269
 * Return:  Success:  Non-negative length of name, with information
1270
 *        in NAME buffer
1271
 *    Failure:  Negative
1272
 *
1273
 *-------------------------------------------------------------------------
1274
 */
1275
ssize_t
1276
H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
1277
                   char *name /*out*/, size_t size, hid_t lapl_id)
1278
0
{
1279
0
    H5VL_object_t       *vol_obj = NULL;    /* Attribute object for ID */
1280
0
    H5VL_attr_get_args_t vol_cb_args;       /* Arguments to VOL callback */
1281
0
    size_t               attr_name_len = 0; /* Length of attribute name */
1282
0
    ssize_t              ret_value;         /* Return value */
1283
1284
0
    FUNC_ENTER_API(FAIL)
1285
1286
    /* Check args */
1287
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1288
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1289
0
    if (!obj_name || !*obj_name)
1290
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
1291
0
    if (!name && size)
1292
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name cannot be NULL if size is non-zero");
1293
0
    if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1294
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified");
1295
0
    if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1296
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified");
1297
1298
    /* Verify access property list and set up collective metadata if appropriate */
1299
0
    if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, false) < 0)
1300
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info");
1301
1302
    /* Get the object */
1303
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
1304
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
1305
1306
    /* Set up VOL callback arguments */
1307
0
    vol_cb_args.op_type                                               = H5VL_ATTR_GET_NAME;
1308
0
    vol_cb_args.args.get_name.loc_params.type                         = H5VL_OBJECT_BY_IDX;
1309
0
    vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.name     = obj_name;
1310
0
    vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.idx_type = idx_type;
1311
0
    vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.order    = order;
1312
0
    vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.n        = n;
1313
0
    vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.lapl_id  = lapl_id;
1314
0
    vol_cb_args.args.get_name.loc_params.obj_type                     = H5I_get_type(loc_id);
1315
0
    vol_cb_args.args.get_name.buf_size                                = size;
1316
0
    vol_cb_args.args.get_name.buf                                     = name;
1317
0
    vol_cb_args.args.get_name.attr_name_len                           = &attr_name_len;
1318
1319
    /* Get the name */
1320
0
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1321
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get name");
1322
1323
    /* Set the return value */
1324
0
    ret_value = (ssize_t)attr_name_len;
1325
1326
0
done:
1327
0
    FUNC_LEAVE_API(ret_value)
1328
0
} /* end H5Aget_name_by_idx() */
1329
1330
/*-------------------------------------------------------------------------
1331
 * Function:  H5Aget_storage_size
1332
 *
1333
 * Purpose: Returns the amount of storage size that is required for this
1334
 *    attribute.
1335
 *
1336
 * Return:  Success:  The amount of storage size allocated for the
1337
 *        attribute.  The return value may be zero
1338
 *                              if no data has been stored.
1339
 *
1340
 *    Failure:  Zero
1341
 *
1342
 *-------------------------------------------------------------------------
1343
 */
1344
hsize_t
1345
H5Aget_storage_size(hid_t attr_id)
1346
0
{
1347
0
    H5VL_object_t       *vol_obj = NULL;   /* Attribute object for ID */
1348
0
    H5VL_attr_get_args_t vol_cb_args;      /* Arguments to VOL callback */
1349
0
    hsize_t              storage_size = 0; /* Storage size of attribute */
1350
0
    hsize_t              ret_value;        /* Return value */
1351
1352
0
    FUNC_ENTER_API(0)
1353
1354
    /* Check arguments */
1355
0
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1356
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute");
1357
1358
    /* Set up VOL callback arguments */
1359
0
    vol_cb_args.op_type                         = H5VL_ATTR_GET_STORAGE_SIZE;
1360
0
    vol_cb_args.args.get_storage_size.data_size = &storage_size;
1361
1362
    /* Get the storage size */
1363
0
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1364
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, 0, "unable to get storage size");
1365
1366
    /* Set the return value */
1367
0
    ret_value = storage_size;
1368
1369
0
done:
1370
0
    FUNC_LEAVE_API(ret_value)
1371
0
} /* end H5Aget_storage_size() */
1372
1373
/*-------------------------------------------------------------------------
1374
 * Function:  H5Aget_info
1375
 *
1376
 * Purpose: Retrieve information about an attribute.
1377
 *
1378
 * Return:  Success:  Non-negative
1379
 *    Failure:  Negative
1380
 *
1381
 *-------------------------------------------------------------------------
1382
 */
1383
herr_t
1384
H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/)
1385
0
{
1386
0
    H5VL_object_t       *vol_obj = NULL;      /* Attribute object for ID */
1387
0
    H5VL_attr_get_args_t vol_cb_args;         /* Arguments to VOL callback */
1388
0
    herr_t               ret_value = SUCCEED; /* Return value */
1389
1390
0
    FUNC_ENTER_API(FAIL)
1391
1392
    /* Check args */
1393
0
    if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1394
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute");
1395
0
    if (!ainfo)
1396
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "attribute_info parameter cannot be NULL");
1397
1398
    /* Set up VOL callback arguments */
1399
0
    vol_cb_args.op_type                           = H5VL_ATTR_GET_INFO;
1400
0
    vol_cb_args.args.get_info.loc_params.type     = H5VL_OBJECT_BY_SELF;
1401
0
    vol_cb_args.args.get_info.loc_params.obj_type = H5I_get_type(attr_id);
1402
0
    vol_cb_args.args.get_info.attr_name           = NULL;
1403
0
    vol_cb_args.args.get_info.ainfo               = ainfo;
1404
1405
    /* Get the attribute information */
1406
0
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1407
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info");
1408
1409
0
done:
1410
0
    FUNC_LEAVE_API(ret_value)
1411
0
} /* end H5Aget_info() */
1412
1413
/*-------------------------------------------------------------------------
1414
 * Function:  H5Aget_info_by_name
1415
 *
1416
 * Purpose: Retrieve information about an attribute by name.
1417
 *
1418
 * Return:  Success:  Non-negative
1419
 *    Failure:  Negative
1420
 *
1421
 *-------------------------------------------------------------------------
1422
 */
1423
herr_t
1424
H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo /*out*/,
1425
                    hid_t lapl_id)
1426
0
{
1427
0
    H5VL_object_t       *vol_obj = NULL;      /* Attribute object for ID */
1428
0
    H5VL_attr_get_args_t vol_cb_args;         /* Arguments to VOL callback */
1429
0
    herr_t               ret_value = SUCCEED; /* Return value */
1430
1431
0
    FUNC_ENTER_API(FAIL)
1432
1433
    /* Check args */
1434
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1435
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1436
0
    if (!obj_name || !*obj_name)
1437
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name");
1438
0
    if (!attr_name || !*attr_name)
1439
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name");
1440
0
    if (NULL == ainfo)
1441
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid info pointer");
1442
1443
    /* Verify access property list and set up collective metadata if appropriate */
1444
0
    if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, false) < 0)
1445
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info");
1446
1447
    /* Get the object */
1448
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
1449
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
1450
1451
    /* Set up VOL callback arguments */
1452
0
    vol_cb_args.op_type                                               = H5VL_ATTR_GET_INFO;
1453
0
    vol_cb_args.args.get_info.loc_params.type                         = H5VL_OBJECT_BY_NAME;
1454
0
    vol_cb_args.args.get_info.loc_params.loc_data.loc_by_name.name    = obj_name;
1455
0
    vol_cb_args.args.get_info.loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
1456
0
    vol_cb_args.args.get_info.loc_params.obj_type                     = H5I_get_type(loc_id);
1457
0
    vol_cb_args.args.get_info.attr_name                               = attr_name;
1458
0
    vol_cb_args.args.get_info.ainfo                                   = ainfo;
1459
1460
    /* Get the attribute information */
1461
0
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1462
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info");
1463
1464
0
done:
1465
0
    FUNC_LEAVE_API(ret_value)
1466
0
} /* end H5Aget_info_by_name() */
1467
1468
/*-------------------------------------------------------------------------
1469
 * Function:  H5Aget_info_by_idx
1470
 *
1471
 * Purpose: Retrieve information about an attribute, according to the
1472
 *    order within an index.
1473
 *
1474
 * Return:  Success:  Non-negative with information in AINFO
1475
 *    Failure:  Negative
1476
 *
1477
 *-------------------------------------------------------------------------
1478
 */
1479
herr_t
1480
H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
1481
                   H5A_info_t *ainfo /*out*/, hid_t lapl_id)
1482
0
{
1483
0
    H5VL_object_t       *vol_obj = NULL;      /* Attribute object for ID */
1484
0
    H5VL_attr_get_args_t vol_cb_args;         /* Arguments to VOL callback */
1485
0
    herr_t               ret_value = SUCCEED; /* Return value */
1486
1487
0
    FUNC_ENTER_API(FAIL)
1488
1489
    /* Check args */
1490
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1491
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1492
0
    if (!obj_name || !*obj_name)
1493
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
1494
0
    if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1495
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified");
1496
0
    if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1497
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified");
1498
0
    if (NULL == ainfo)
1499
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid info pointer");
1500
1501
    /* Verify access property list and set up collective metadata if appropriate */
1502
0
    if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, false) < 0)
1503
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info");
1504
1505
    /* Get the object */
1506
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
1507
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
1508
1509
    /* Set up VOL callback arguments */
1510
0
    vol_cb_args.op_type                                               = H5VL_ATTR_GET_INFO;
1511
0
    vol_cb_args.args.get_info.loc_params.type                         = H5VL_OBJECT_BY_IDX;
1512
0
    vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.name     = obj_name;
1513
0
    vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.idx_type = idx_type;
1514
0
    vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.order    = order;
1515
0
    vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.n        = n;
1516
0
    vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.lapl_id  = lapl_id;
1517
0
    vol_cb_args.args.get_info.loc_params.obj_type                     = H5I_get_type(loc_id);
1518
0
    vol_cb_args.args.get_info.attr_name                               = NULL;
1519
0
    vol_cb_args.args.get_info.ainfo                                   = ainfo;
1520
1521
    /* Get the attribute information */
1522
0
    if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1523
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info");
1524
1525
0
done:
1526
0
    FUNC_LEAVE_API(ret_value)
1527
0
} /* end H5Aget_info_by_idx() */
1528
1529
/*--------------------------------------------------------------------------
1530
 NAME
1531
    H5A__rename_common
1532
 PURPOSE
1533
    Common helper routine for sync/async attribute rename operations
1534
 RETURNS
1535
    Non-negative on success/Negative on failure
1536
--------------------------------------------------------------------------*/
1537
static herr_t
1538
H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name,
1539
                   const char *new_name, void **token_ptr)
1540
0
{
1541
0
    herr_t ret_value = SUCCEED; /* Return value */
1542
1543
0
    FUNC_ENTER_PACKAGE
1544
1545
    /* Sanity checks */
1546
0
    assert(vol_obj);
1547
0
    assert(loc_params);
1548
0
    assert(old_name);
1549
0
    assert(new_name);
1550
1551
    /* Avoid thrashing things if the names are the same */
1552
0
    if (strcmp(old_name, new_name) != 0) {
1553
0
        H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */
1554
1555
        /* Set up VOL callback arguments */
1556
0
        vol_cb_args.op_type              = H5VL_ATTR_RENAME;
1557
0
        vol_cb_args.args.rename.old_name = old_name;
1558
0
        vol_cb_args.args.rename.new_name = new_name;
1559
1560
        /* Rename the attribute */
1561
0
        if (H5VL_attr_specific(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
1562
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute from '%s' to '%s'", old_name,
1563
0
                        new_name);
1564
0
    }
1565
1566
0
done:
1567
0
    FUNC_LEAVE_NOAPI(ret_value)
1568
0
} /* H5A__rename_common() */
1569
1570
/*--------------------------------------------------------------------------
1571
 NAME
1572
    H5A__rename_api_common
1573
 PURPOSE
1574
    Common helper routine for sync/async attribute rename operations
1575
 RETURNS
1576
    Non-negative on success/Negative on failure
1577
--------------------------------------------------------------------------*/
1578
static herr_t
1579
H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name, void **token_ptr,
1580
                       H5VL_object_t **_vol_obj_ptr)
1581
0
{
1582
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
1583
0
    H5VL_object_t **vol_obj_ptr =
1584
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
1585
0
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
1586
0
    herr_t            ret_value = SUCCEED;            /* Return value */
1587
1588
0
    FUNC_ENTER_PACKAGE
1589
1590
    /* Check arguments */
1591
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1592
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1593
0
    if (!old_name)
1594
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL");
1595
0
    if (!*old_name)
1596
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be an empty string");
1597
0
    if (!new_name)
1598
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be NULL");
1599
0
    if (!*new_name)
1600
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string");
1601
1602
    /* Set up object access arguments */
1603
0
    if (H5VL_setup_loc_args(loc_id, vol_obj_ptr, &loc_params) < 0)
1604
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments");
1605
1606
    /* Rename the attribute */
1607
0
    if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0)
1608
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute");
1609
1610
0
done:
1611
0
    FUNC_LEAVE_NOAPI(ret_value)
1612
0
} /* H5A__rename_api_common() */
1613
1614
/*-------------------------------------------------------------------------
1615
 * Function:    H5Arename
1616
 *
1617
 * Purpose:     Rename an attribute
1618
 *
1619
 * Return:      Success:    Non-negative
1620
 *              Failure:    Negative
1621
 *
1622
 *-------------------------------------------------------------------------
1623
 */
1624
herr_t
1625
H5Arename(hid_t loc_id, const char *old_name, const char *new_name)
1626
0
{
1627
0
    herr_t ret_value = SUCCEED; /* Return value */
1628
1629
0
    FUNC_ENTER_API(FAIL)
1630
1631
    /* Synchronously rename the attribute */
1632
0
    if (H5A__rename_api_common(loc_id, old_name, new_name, NULL, NULL) < 0)
1633
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute");
1634
1635
0
done:
1636
0
    FUNC_LEAVE_API(ret_value)
1637
0
} /* H5Arename() */
1638
1639
/*--------------------------------------------------------------------------
1640
 *  NAME
1641
 *      H5Arename_async
1642
 *  PURPOSE
1643
 *      Asynchronous version of H5Arename
1644
 *  RETURNS
1645
 *      Non-negative on success/Negative on failure
1646
 *--------------------------------------------------------------------------*/
1647
herr_t
1648
H5Arename_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
1649
                const char *old_name, const char *new_name, hid_t es_id)
1650
0
{
1651
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
1652
0
    void          *token     = NULL;            /* Request token for async operation        */
1653
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1654
0
    herr_t         ret_value = SUCCEED;         /* Return value */
1655
1656
0
    FUNC_ENTER_API(FAIL)
1657
1658
    /* Set up request token pointer for asynchronous operation */
1659
0
    if (H5ES_NONE != es_id)
1660
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
1661
1662
    /* Asynchronously rename the attribute */
1663
0
    if (H5A__rename_api_common(loc_id, old_name, new_name, token_ptr, &vol_obj) < 0)
1664
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously rename attribute");
1665
1666
    /* If a token was created, add the token to the event set */
1667
0
    if (NULL != token)
1668
        /* clang-format off */
1669
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
1670
0
                        H5ARG_TRACE7(__func__, "*s*sIui*s*si", app_file, app_func, app_line, loc_id, old_name, new_name, es_id)) < 0)
1671
            /* clang-format on */
1672
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1673
1674
0
done:
1675
0
    FUNC_LEAVE_API(ret_value)
1676
0
} /* H5Arename_async() */
1677
1678
/*--------------------------------------------------------------------------
1679
 NAME
1680
    H5A__rename_by_name_api_common
1681
 PURPOSE
1682
    Common helper routine for sync/async attribute rename operations
1683
 RETURNS
1684
    Non-negative on success/Negative on failure
1685
--------------------------------------------------------------------------*/
1686
static herr_t
1687
H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_name, const char *new_name,
1688
                               hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
1689
0
{
1690
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
1691
0
    H5VL_object_t **vol_obj_ptr =
1692
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
1693
0
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
1694
0
    herr_t            ret_value = SUCCEED;            /* Return value */
1695
1696
0
    FUNC_ENTER_PACKAGE
1697
1698
    /* Check arguments */
1699
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1700
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1701
1702
0
    if (!old_name)
1703
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL");
1704
0
    if (!*old_name)
1705
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be an empty string");
1706
0
    if (!new_name)
1707
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be NULL");
1708
0
    if (!*new_name)
1709
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string");
1710
1711
    /* obj_name is verified in H5VL_setup_name_args() */
1712
    /* Set up object access arguments */
1713
0
    if (H5VL_setup_name_args(loc_id, obj_name, true, lapl_id, vol_obj_ptr, &loc_params) < 0)
1714
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments");
1715
1716
    /* Rename the attribute */
1717
0
    if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0)
1718
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute");
1719
1720
0
done:
1721
0
    FUNC_LEAVE_NOAPI(ret_value)
1722
0
} /* H5A__rename_by_name_api_common() */
1723
1724
/*-------------------------------------------------------------------------
1725
 * Function:    H5Arename_by_name
1726
 *
1727
 * Purpose:     Rename an attribute
1728
 *
1729
 * Return:      Success:    Non-negative
1730
 *              Failure:    Negative
1731
 *
1732
 *-------------------------------------------------------------------------
1733
 */
1734
herr_t
1735
H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, const char *new_attr_name,
1736
                  hid_t lapl_id)
1737
0
{
1738
0
    herr_t ret_value = SUCCEED; /* Return value */
1739
1740
0
    FUNC_ENTER_API(FAIL)
1741
1742
    /* Synchronously rename the attribute */
1743
0
    if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, NULL, NULL) <
1744
0
        0)
1745
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute");
1746
1747
0
done:
1748
0
    FUNC_LEAVE_API(ret_value)
1749
0
} /* H5Arename_by_name() */
1750
1751
/*--------------------------------------------------------------------------
1752
 *  NAME
1753
 *      H5Arename_by_name_async
1754
 *  PURPOSE
1755
 *      Asynchronous version of H5Arename_by_name
1756
 *  RETURNS
1757
 *      Non-negative on success/Negative on failure
1758
 *--------------------------------------------------------------------------*/
1759
herr_t
1760
H5Arename_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
1761
                        const char *obj_name, const char *old_attr_name, const char *new_attr_name,
1762
                        hid_t lapl_id, hid_t es_id)
1763
0
{
1764
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
1765
0
    void          *token     = NULL;            /* Request token for async operation        */
1766
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1767
0
    herr_t         ret_value = SUCCEED;         /* Return value */
1768
1769
0
    FUNC_ENTER_API(FAIL)
1770
1771
    /* Set up request token pointer for asynchronous operation */
1772
0
    if (H5ES_NONE != es_id)
1773
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
1774
1775
    /* Asynchronously rename the attribute */
1776
0
    if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, token_ptr,
1777
0
                                       &vol_obj) < 0)
1778
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute");
1779
1780
    /* If a token was created, add the token to the event set */
1781
0
    if (NULL != token)
1782
        /* clang-format off */
1783
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
1784
0
                        H5ARG_TRACE9(__func__, "*s*sIui*s*s*sii", app_file, app_func, app_line, loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, es_id)) < 0)
1785
            /* clang-format on */
1786
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1787
1788
0
done:
1789
0
    FUNC_LEAVE_API(ret_value)
1790
0
} /* H5Arename_by_name_async() */
1791
1792
/*--------------------------------------------------------------------------
1793
 NAME
1794
    H5Aiterate2
1795
 PURPOSE
1796
    Calls a user's function for each attribute on an object
1797
 USAGE
1798
    herr_t H5Aiterate2(loc_id, idx_type, order, idx, op, op_data)
1799
        hid_t loc_id;           IN: Base location for object
1800
        H5_index_t idx_type;    IN: Type of index to use
1801
        H5_iter_order_t order;  IN: Order to iterate over index
1802
        hsize_t *idx;           IN/OUT: Starting (IN) & Ending (OUT) attribute
1803
                                    in index & order
1804
        H5A_operator2_t op;     IN: User's function to pass each attribute to
1805
        void *op_data;          IN/OUT: User's data to pass through to iterator
1806
                                    operator function
1807
 RETURNS
1808
        Returns a negative value if an error occurs, the return value of the
1809
    last operator if it was non-zero (which can be a negative value), or zero
1810
    if all attributes were processed.
1811
1812
 DESCRIPTION
1813
        This function iterates over the attributes of dataset or group
1814
    specified with 'loc_id' & 'obj_name'.  For each attribute of the object,
1815
    the 'op_data' and some additional information (specified below) are passed
1816
    to the 'op' function.  The iteration begins with the '*idx'
1817
    object in the group and the next attribute to be processed by the operator
1818
    is returned in '*idx'.
1819
        The operation receives the ID for the group or dataset being iterated
1820
    over ('loc_id'), the name of the current attribute about the object
1821
    ('attr_name'), the attribute's "info" struct ('ainfo') and the pointer to
1822
    the operator data passed into H5Aiterate2 ('op_data').  The return values
1823
    from an operator are:
1824
        A. Zero causes the iterator to continue, returning zero when all
1825
            attributes have been processed.
1826
        B. Positive causes the iterator to immediately return that positive
1827
            value, indicating short-circuit success.  The iterator can be
1828
            restarted at the next attribute.
1829
        C. Negative causes the iterator to immediately return that value,
1830
            indicating failure.  The iterator can be restarted at the next
1831
            attribute.
1832
--------------------------------------------------------------------------*/
1833
herr_t
1834
H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */,
1835
            H5A_operator2_t op, void *op_data)
1836
0
{
1837
0
    H5VL_object_t            *vol_obj = NULL; /* Object for loc_id */
1838
0
    H5VL_loc_params_t         loc_params;     /* Location parameters for object access */
1839
0
    H5VL_attr_specific_args_t vol_cb_args;    /* Arguments to VOL callback */
1840
0
    herr_t                    ret_value;      /* Return value */
1841
1842
0
    FUNC_ENTER_API(FAIL)
1843
1844
    /* Check arguments */
1845
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1846
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1847
0
    if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1848
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified");
1849
0
    if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1850
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified");
1851
1852
    /* Get the loc object */
1853
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
1854
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier");
1855
1856
    /* Set the location access parameters */
1857
0
    loc_params.type     = H5VL_OBJECT_BY_SELF;
1858
0
    loc_params.obj_type = H5I_get_type(loc_id);
1859
1860
    /* Set up VOL callback arguments */
1861
0
    vol_cb_args.op_type               = H5VL_ATTR_ITER;
1862
0
    vol_cb_args.args.iterate.idx_type = idx_type;
1863
0
    vol_cb_args.args.iterate.order    = order;
1864
0
    vol_cb_args.args.iterate.idx      = idx;
1865
0
    vol_cb_args.args.iterate.op       = op;
1866
0
    vol_cb_args.args.iterate.op_data  = op_data;
1867
1868
    /* Iterate over attributes */
1869
0
    if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT,
1870
0
                                        H5_REQUEST_NULL)) < 0)
1871
0
        HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
1872
1873
0
done:
1874
0
    FUNC_LEAVE_API(ret_value)
1875
0
} /* H5Aiterate2() */
1876
1877
/*--------------------------------------------------------------------------
1878
 NAME
1879
    H5Aiterate_by_name
1880
 PURPOSE
1881
    Calls a user's function for each attribute on an object
1882
 USAGE
1883
    herr_t H5Aiterate_by_name(loc_id, obj_name, idx_type, order, idx, op, op_data, lapl_id)
1884
        hid_t loc_id;           IN: Base location for object
1885
        const char *obj_name;   IN: Name of object relative to location
1886
        H5_index_t idx_type;    IN: Type of index to use
1887
        H5_iter_order_t order;  IN: Order to iterate over index
1888
        hsize_t *idx;           IN/OUT: Starting (IN) & Ending (OUT) attribute
1889
                                    in index & order
1890
        H5A_operator2_t op;     IN: User's function to pass each attribute to
1891
        void *op_data;          IN/OUT: User's data to pass through to iterator
1892
                                    operator function
1893
        hid_t lapl_id;          IN: Link access property list
1894
 RETURNS
1895
        Returns a negative value if an error occurs, the return value of the
1896
    last operator if it was non-zero (which can be a negative value), or zero
1897
    if all attributes were processed.
1898
1899
 DESCRIPTION
1900
        This function iterates over the attributes of dataset or group
1901
    specified with 'loc_id' & 'obj_name'.  For each attribute of the object,
1902
    the 'op_data' and some additional information (specified below) are passed
1903
    to the 'op' function.  The iteration begins with the '*idx'
1904
    object in the group and the next attribute to be processed by the operator
1905
    is returned in '*idx'.
1906
        The operation receives the ID for the group or dataset being iterated
1907
    over ('loc_id'), the name of the current attribute about the object
1908
    ('attr_name'), the attribute's "info" struct ('ainfo') and the pointer to
1909
    the operator data passed into H5Aiterate_by_name ('op_data').  The return values
1910
    from an operator are:
1911
        A. Zero causes the iterator to continue, returning zero when all
1912
            attributes have been processed.
1913
        B. Positive causes the iterator to immediately return that positive
1914
            value, indicating short-circuit success.  The iterator can be
1915
            restarted at the next attribute.
1916
        C. Negative causes the iterator to immediately return that value,
1917
            indicating failure.  The iterator can be restarted at the next
1918
            attribute.
1919
--------------------------------------------------------------------------*/
1920
herr_t
1921
H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order,
1922
                   hsize_t *idx /*in,out */, H5A_operator2_t op, void *op_data, hid_t lapl_id)
1923
0
{
1924
0
    H5VL_object_t            *vol_obj = NULL;      /* Object for loc_id */
1925
0
    H5VL_loc_params_t         loc_params;          /* Location parameters for object access */
1926
0
    H5VL_attr_specific_args_t vol_cb_args;         /* Arguments to VOL callback */
1927
0
    herr_t                    ret_value = SUCCEED; /* Return value */
1928
1929
0
    FUNC_ENTER_API(FAIL)
1930
1931
    /* Check arguments */
1932
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1933
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1934
0
    if (!obj_name || !*obj_name)
1935
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name");
1936
0
    if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1937
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified");
1938
0
    if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1939
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified");
1940
1941
    /* Verify access property list and set up collective metadata if appropriate */
1942
0
    if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, false) < 0)
1943
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info");
1944
1945
    /* get the loc object */
1946
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
1947
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier");
1948
1949
    /* Set the location access parameters */
1950
0
    loc_params.type                         = H5VL_OBJECT_BY_NAME;
1951
0
    loc_params.obj_type                     = H5I_get_type(loc_id);
1952
0
    loc_params.loc_data.loc_by_name.name    = obj_name;
1953
0
    loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
1954
1955
    /* Set up VOL callback arguments */
1956
0
    vol_cb_args.op_type               = H5VL_ATTR_ITER;
1957
0
    vol_cb_args.args.iterate.idx_type = idx_type;
1958
0
    vol_cb_args.args.iterate.order    = order;
1959
0
    vol_cb_args.args.iterate.idx      = idx;
1960
0
    vol_cb_args.args.iterate.op       = op;
1961
0
    vol_cb_args.args.iterate.op_data  = op_data;
1962
1963
    /* Iterate over attributes */
1964
0
    if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT,
1965
0
                                        H5_REQUEST_NULL)) < 0)
1966
0
        HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed");
1967
1968
0
done:
1969
0
    FUNC_LEAVE_API(ret_value)
1970
0
} /* H5Aiterate_by_name() */
1971
1972
/*--------------------------------------------------------------------------
1973
 NAME
1974
    H5Adelete
1975
 PURPOSE
1976
    Deletes an attribute from a location
1977
 USAGE
1978
    herr_t H5Adelete(loc_id, name)
1979
        hid_t loc_id;       IN: Object (dataset or group) to have attribute deleted from
1980
        const char *name;   IN: Name of attribute to delete
1981
 RETURNS
1982
    Non-negative on success/Negative on failure
1983
 DESCRIPTION
1984
    This function removes the named attribute from a dataset or group.
1985
--------------------------------------------------------------------------*/
1986
herr_t
1987
H5Adelete(hid_t loc_id, const char *name)
1988
0
{
1989
0
    H5VL_object_t            *vol_obj = NULL;      /* Object for loc_id */
1990
0
    H5VL_loc_params_t         loc_params;          /* Location parameters for object access */
1991
0
    H5VL_attr_specific_args_t vol_cb_args;         /* Arguments to VOL callback */
1992
0
    herr_t                    ret_value = SUCCEED; /* Return value */
1993
1994
0
    FUNC_ENTER_API(FAIL)
1995
1996
    /* Check arguments */
1997
0
    if (H5I_ATTR == H5I_get_type(loc_id))
1998
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
1999
0
    if (!name)
2000
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL");
2001
0
    if (!*name)
2002
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string");
2003
2004
    /* Set up collective metadata if appropriate */
2005
0
    if (H5CX_set_loc(loc_id) < 0)
2006
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read");
2007
2008
    /* Get the object */
2009
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
2010
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
2011
2012
    /* Set the location access parameters */
2013
0
    loc_params.type     = H5VL_OBJECT_BY_SELF;
2014
0
    loc_params.obj_type = H5I_get_type(loc_id);
2015
2016
    /* Set up VOL callback arguments */
2017
0
    vol_cb_args.op_type       = H5VL_ATTR_DELETE;
2018
0
    vol_cb_args.args.del.name = name;
2019
2020
    /* Delete the attribute */
2021
0
    if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2022
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute");
2023
2024
0
done:
2025
0
    FUNC_LEAVE_API(ret_value)
2026
0
} /* H5Adelete() */
2027
2028
/*--------------------------------------------------------------------------
2029
 NAME
2030
    H5Adelete_by_name
2031
 PURPOSE
2032
    Deletes an attribute from a location
2033
 USAGE
2034
    herr_t H5Adelete_by_name(loc_id, obj_name, attr_name, lapl_id)
2035
        hid_t loc_id;           IN: Base location for object
2036
        const char *obj_name;   IN: Name of object relative to location
2037
        const char *attr_name;  IN: Name of attribute to delete
2038
        hid_t lapl_id;          IN: Link access property list
2039
 RETURNS
2040
    Non-negative on success/Negative on failure
2041
 DESCRIPTION
2042
    This function removes the named attribute from an object.
2043
--------------------------------------------------------------------------*/
2044
herr_t
2045
H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id)
2046
0
{
2047
0
    H5VL_object_t            *vol_obj = NULL;      /* Object for loc_id */
2048
0
    H5VL_loc_params_t         loc_params;          /* Location parameters for object access */
2049
0
    H5VL_attr_specific_args_t vol_cb_args;         /* Arguments to VOL callback */
2050
0
    herr_t                    ret_value = SUCCEED; /* Return value */
2051
2052
0
    FUNC_ENTER_API(FAIL)
2053
2054
    /* Check arguments */
2055
0
    if (H5I_ATTR == H5I_get_type(loc_id))
2056
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
2057
0
    if (!obj_name || !*obj_name)
2058
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name");
2059
0
    if (!attr_name || !*attr_name)
2060
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name");
2061
2062
    /* Verify access property list and set up collective metadata if appropriate */
2063
0
    if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, true) < 0)
2064
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info");
2065
2066
    /* Get the object */
2067
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
2068
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
2069
2070
    /* Set the location access parameters */
2071
0
    loc_params.type                         = H5VL_OBJECT_BY_NAME;
2072
0
    loc_params.loc_data.loc_by_name.name    = obj_name;
2073
0
    loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
2074
0
    loc_params.obj_type                     = H5I_get_type(loc_id);
2075
2076
    /* Set up VOL callback arguments */
2077
0
    vol_cb_args.op_type       = H5VL_ATTR_DELETE;
2078
0
    vol_cb_args.args.del.name = attr_name;
2079
2080
    /* Delete the attribute */
2081
0
    if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2082
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute");
2083
2084
0
done:
2085
0
    FUNC_LEAVE_API(ret_value)
2086
0
} /* H5Adelete_by_name() */
2087
2088
/*--------------------------------------------------------------------------
2089
 NAME
2090
    H5Adelete_by_idx
2091
 PURPOSE
2092
    Deletes an attribute from a location, according to the order within an index
2093
 USAGE
2094
    herr_t H5Adelete_by_idx(loc_id, obj_name, idx_type, order, n, lapl_id)
2095
        hid_t loc_id;           IN: Base location for object
2096
        const char *obj_name;   IN: Name of object relative to location
2097
        H5_index_t idx_type;    IN: Type of index to use
2098
        H5_iter_order_t order;  IN: Order to iterate over index
2099
        hsize_t n;              IN: Offset within index
2100
        hid_t lapl_id;          IN: Link access property list
2101
 RETURNS
2102
    Non-negative on success/Negative on failure
2103
 DESCRIPTION
2104
        This function removes an attribute from an object, using the IDX_TYPE
2105
    index to delete the N'th attribute in ORDER direction in the index.  The
2106
    object is specified relative to the LOC_ID with the OBJ_NAME path.  To
2107
    remove an attribute on the object specified by LOC_ID, pass in "." for
2108
    OBJ_NAME.  The link access property list, LAPL_ID, controls aspects of
2109
    the group hierarchy traversal when using the OBJ_NAME to locate the final
2110
    object to operate on.
2111
--------------------------------------------------------------------------*/
2112
herr_t
2113
H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
2114
                 hid_t lapl_id)
2115
0
{
2116
0
    H5VL_object_t            *vol_obj = NULL;      /* Object for loc_id */
2117
0
    H5VL_loc_params_t         loc_params;          /* Location parameters for object access */
2118
0
    H5VL_attr_specific_args_t vol_cb_args;         /* Arguments to VOL callback */
2119
0
    herr_t                    ret_value = SUCCEED; /* Return value */
2120
2121
0
    FUNC_ENTER_API(FAIL)
2122
2123
    /* check arguments */
2124
0
    if (H5I_ATTR == H5I_get_type(loc_id))
2125
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
2126
0
    if (!obj_name || !*obj_name)
2127
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name");
2128
0
    if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
2129
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified");
2130
0
    if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
2131
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified");
2132
2133
    /* Verify access property list and set up collective metadata if appropriate */
2134
0
    if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, true) < 0)
2135
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info");
2136
2137
    /* get the object */
2138
0
    if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
2139
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
2140
2141
    /* Set the location access parameters */
2142
0
    loc_params.type                         = H5VL_OBJECT_BY_NAME;
2143
0
    loc_params.loc_data.loc_by_name.name    = obj_name;
2144
0
    loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
2145
0
    loc_params.obj_type                     = H5I_get_type(loc_id);
2146
2147
    /* Set up VOL callback arguments */
2148
0
    vol_cb_args.op_type                     = H5VL_ATTR_DELETE_BY_IDX;
2149
0
    vol_cb_args.args.delete_by_idx.idx_type = idx_type;
2150
0
    vol_cb_args.args.delete_by_idx.order    = order;
2151
0
    vol_cb_args.args.delete_by_idx.n        = n;
2152
2153
    /* Delete the attribute */
2154
0
    if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2155
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute");
2156
2157
0
done:
2158
0
    FUNC_LEAVE_API(ret_value)
2159
0
} /* H5Adelete_by_idx() */
2160
2161
/*-------------------------------------------------------------------------
2162
 * Function:    H5Aclose
2163
 *
2164
 * Purpose:     Closes access to an attribute and releases resources used by
2165
 *              it. It is illegal to subsequently use that same dataset
2166
 *              ID in calls to other attribute functions.
2167
 *
2168
 * Return:      SUCCEED/FAIL
2169
 *
2170
 *-------------------------------------------------------------------------
2171
 */
2172
herr_t
2173
H5Aclose(hid_t attr_id)
2174
76
{
2175
76
    herr_t ret_value = SUCCEED; /* Return value */
2176
2177
152
    FUNC_ENTER_API(FAIL)
2178
2179
    /* Check arguments */
2180
152
    if (H5I_ATTR != H5I_get_type(attr_id))
2181
12
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute ID");
2182
2183
    /* Decrement the counter on the attribute ID. It will be freed if the count
2184
     * reaches zero.
2185
     */
2186
64
    if (H5I_dec_app_ref(attr_id) < 0)
2187
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "decrementing attribute ID failed");
2188
2189
76
done:
2190
76
    FUNC_LEAVE_API(ret_value)
2191
64
} /* H5Aclose() */
2192
2193
/*-------------------------------------------------------------------------
2194
 * Function:    H5Aclose_async
2195
 *
2196
 * Purpose:     Asynchronous version of H5Aclose
2197
 *
2198
 * Return:      SUCCEED/FAIL
2199
 *
2200
 *-------------------------------------------------------------------------
2201
 */
2202
herr_t
2203
H5Aclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t es_id)
2204
0
{
2205
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
2206
0
    H5VL_t        *connector = NULL;            /* VOL connector */
2207
0
    void          *token     = NULL;            /* Request token for async operation        */
2208
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
2209
0
    herr_t         ret_value = SUCCEED;         /* Return value */
2210
2211
0
    FUNC_ENTER_API(FAIL)
2212
2213
    /* Check arguments */
2214
0
    if (H5I_ATTR != H5I_get_type(attr_id))
2215
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a attribute ID");
2216
2217
    /* Prepare for possible asynchronous operation */
2218
0
    if (H5ES_NONE != es_id) {
2219
        /* Get attribute object's connector */
2220
0
        if (NULL == (vol_obj = H5VL_vol_object(attr_id)))
2221
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute");
2222
2223
        /* Increase connector's refcount, so it doesn't get closed if closing
2224
         * the attribute closes the file */
2225
0
        connector = vol_obj->connector;
2226
0
        H5VL_conn_inc_rc(connector);
2227
2228
        /* Point at token for operation to set up */
2229
0
        token_ptr = &token;
2230
0
    } /* end if */
2231
2232
    /* Decrement the counter on the attribute ID. It will be freed if the count
2233
     * reaches zero.
2234
     */
2235
0
    if (H5I_dec_app_ref_async(attr_id, token_ptr) < 0)
2236
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "decrementing attribute ID failed");
2237
2238
    /* If a token was created, add the token to the event set */
2239
0
    if (NULL != token)
2240
        /* clang-format off */
2241
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
2242
0
                        H5ARG_TRACE5(__func__, "*s*sIuii", app_file, app_func, app_line, attr_id, es_id)) < 0)
2243
            /* clang-format on */
2244
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set");
2245
2246
0
done:
2247
0
    if (connector && H5VL_conn_dec_rc(connector) < 0)
2248
0
        HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't decrement ref count on connector");
2249
2250
0
    FUNC_LEAVE_API(ret_value)
2251
0
} /* H5Aclose_async() */
2252
2253
/*--------------------------------------------------------------------------
2254
 *  NAME
2255
 *      H5A__exists_common
2256
 *  PURPOSE
2257
 *      Common helper routine for sync/async check if an attribute exists
2258
 *  RETURNS
2259
 *      Non-negative on success/Negative on failure
2260
 *--------------------------------------------------------------------------*/
2261
static herr_t
2262
H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
2263
                   bool *attr_exists, void **token_ptr)
2264
107
{
2265
107
    H5VL_attr_specific_args_t vol_cb_args;         /* Arguments to VOL callback */
2266
107
    herr_t                    ret_value = SUCCEED; /* Return value */
2267
2268
107
    FUNC_ENTER_PACKAGE
2269
2270
    /* Sanity checks */
2271
107
    assert(vol_obj);
2272
107
    assert(loc_params);
2273
2274
    /* Check arguments */
2275
107
    if (!attr_name || !*attr_name)
2276
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name");
2277
2278
    /* Set up VOL callback arguments */
2279
107
    vol_cb_args.op_type            = H5VL_ATTR_EXISTS;
2280
107
    vol_cb_args.args.exists.name   = attr_name;
2281
107
    vol_cb_args.args.exists.exists = attr_exists;
2282
2283
    /* Check if the attribute exists */
2284
107
    if (H5VL_attr_specific(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
2285
12
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists");
2286
2287
107
done:
2288
107
    FUNC_LEAVE_NOAPI(ret_value)
2289
107
} /* H5A__exists_common() */
2290
2291
/*--------------------------------------------------------------------------
2292
 *  NAME
2293
 *      H5A__exists_api_common
2294
 *  PURPOSE
2295
 *      Common helper routine for sync/async check if an attribute exists
2296
 *  RETURNS
2297
 *      Non-negative on success/Negative on failure
2298
 *--------------------------------------------------------------------------*/
2299
static herr_t
2300
H5A__exists_api_common(hid_t obj_id, const char *attr_name, bool *attr_exists, void **token_ptr,
2301
                       H5VL_object_t **_vol_obj_ptr)
2302
0
{
2303
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
2304
0
    H5VL_object_t **vol_obj_ptr =
2305
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
2306
0
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
2307
0
    herr_t            ret_value = SUCCEED;            /* Return value */
2308
2309
0
    FUNC_ENTER_PACKAGE
2310
2311
    /* Check arguments */
2312
0
    if (H5I_ATTR == H5I_get_type(obj_id))
2313
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
2314
0
    if (!attr_name || !*attr_name)
2315
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name");
2316
0
    if (NULL == attr_exists)
2317
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence");
2318
2319
    /* Set up object access arguments */
2320
0
    if (H5VL_setup_self_args(obj_id, vol_obj_ptr, &loc_params) < 0)
2321
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments");
2322
2323
    /* Check if the attribute exists */
2324
0
    if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0)
2325
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists");
2326
2327
0
done:
2328
0
    FUNC_LEAVE_NOAPI(ret_value)
2329
0
} /* H5A__exists_api_common() */
2330
2331
/*-------------------------------------------------------------------------
2332
 * Function:  H5Aexists
2333
 *
2334
 * Purpose: Checks if an attribute with a given name exists on an opened
2335
 *              object.
2336
 *
2337
 * Return:  Success:  true/false
2338
 *    Failure:  Negative
2339
 *
2340
 *-------------------------------------------------------------------------
2341
 */
2342
htri_t
2343
H5Aexists(hid_t obj_id, const char *attr_name)
2344
0
{
2345
0
    bool   exists;           /* Flag for attribute existence */
2346
0
    htri_t ret_value = FAIL; /* Return value */
2347
2348
0
    FUNC_ENTER_API(FAIL)
2349
2350
    /* Synchronously check if an attribute exists */
2351
0
    exists = false;
2352
0
    if (H5A__exists_api_common(obj_id, attr_name, &exists, NULL, NULL) < 0)
2353
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't synchronously check if attribute exists");
2354
2355
    /* Set return value */
2356
0
    ret_value = (htri_t)exists;
2357
2358
0
done:
2359
0
    FUNC_LEAVE_API(ret_value)
2360
0
} /* H5Aexists() */
2361
2362
/*--------------------------------------------------------------------------
2363
 * NAME
2364
 *      H5Aexists_async
2365
 * PURPOSE
2366
 *      Asynchronous version of H5Aexists
2367
 * RETURNS
2368
 *      Non-negative on success/Negative on failure
2369
 *--------------------------------------------------------------------------*/
2370
herr_t
2371
H5Aexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id,
2372
                const char *attr_name, hbool_t *attr_exists, hid_t es_id)
2373
0
{
2374
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
2375
0
    void          *token     = NULL;            /* Request token for async operation        */
2376
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
2377
0
    herr_t         ret_value = SUCCEED;         /* Return value */
2378
2379
0
    FUNC_ENTER_API(FAIL)
2380
2381
    /* Set up request token pointer for asynchronous operation */
2382
0
    if (H5ES_NONE != es_id)
2383
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
2384
2385
    /* Asynchronously check if an attribute exists */
2386
0
    if (H5A__exists_api_common(obj_id, attr_name, attr_exists, token_ptr, &vol_obj) < 0)
2387
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't asynchronously check if attribute exists");
2388
2389
    /* If a token was created, add the token to the event set */
2390
0
    if (NULL != token)
2391
        /* clang-format off */
2392
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
2393
0
                        H5ARG_TRACE7(__func__, "*s*sIui*s*bi", app_file, app_func, app_line, obj_id, attr_name, attr_exists, es_id)) < 0)
2394
            /* clang-format on */
2395
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set");
2396
2397
0
done:
2398
0
    FUNC_LEAVE_API(ret_value)
2399
0
} /* H5Aexists_async() */
2400
2401
/*--------------------------------------------------------------------------
2402
 *  NAME
2403
 *      H5A__exists_by_name_api_common
2404
 *  PURPOSE
2405
 *      Common helper routine for sync/async check if an attribute exists
2406
 *  RETURNS
2407
 *      Non-negative on success/Negative on failure
2408
 *--------------------------------------------------------------------------*/
2409
static herr_t
2410
H5A__exists_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, bool *attr_exists,
2411
                               hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
2412
107
{
2413
107
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
2414
107
    H5VL_object_t **vol_obj_ptr =
2415
107
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
2416
107
    H5VL_loc_params_t loc_params;                     /* Location parameters for object access */
2417
107
    herr_t            ret_value = SUCCEED;            /* Return value */
2418
2419
107
    FUNC_ENTER_PACKAGE
2420
2421
    /* Check arguments */
2422
107
    if (H5I_ATTR == H5I_get_type(loc_id))
2423
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute");
2424
107
    if (!attr_name || !*attr_name)
2425
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name");
2426
107
    if (NULL == attr_exists)
2427
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence");
2428
2429
    /* obj_name is verified in H5VL_setup_name_args() */
2430
    /* Set up object access arguments */
2431
107
    if (H5VL_setup_name_args(loc_id, obj_name, false, lapl_id, vol_obj_ptr, &loc_params) < 0)
2432
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments");
2433
2434
    /* Check if the attribute exists */
2435
107
    if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0)
2436
12
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists");
2437
2438
107
done:
2439
107
    FUNC_LEAVE_NOAPI(ret_value)
2440
107
} /* H5A__exists_by_name_api_common() */
2441
2442
/*-------------------------------------------------------------------------
2443
 * Function:  H5Aexists_by_name
2444
 *
2445
 * Purpose: Checks if an attribute with a given name exists on an object.
2446
 *
2447
 * Return:  Success:  true/false
2448
 *        Failure:  Negative
2449
 *
2450
 *-------------------------------------------------------------------------
2451
 */
2452
htri_t
2453
H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id)
2454
107
{
2455
107
    bool   exists;           /* Flag for attribute existence */
2456
107
    htri_t ret_value = FAIL; /* Return value */
2457
2458
214
    FUNC_ENTER_API(FAIL)
2459
2460
    /* Synchronously check if an attribute exists */
2461
214
    exists = false;
2462
214
    if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, &exists, lapl_id, NULL, NULL) < 0)
2463
12
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't synchronously determine if attribute exists by name");
2464
2465
    /* Set return value */
2466
95
    ret_value = (htri_t)exists;
2467
2468
107
done:
2469
107
    FUNC_LEAVE_API(ret_value)
2470
95
} /* H5Aexists_by_name() */
2471
2472
/*--------------------------------------------------------------------------
2473
 * NAME
2474
 *      H5Aexists_by_name_async
2475
 * PURPOSE
2476
 *      Asynchronous version of H5Aexists_by_name
2477
 * RETURNS
2478
 *      Non-negative on success/Negative on failure
2479
 *--------------------------------------------------------------------------*/
2480
herr_t
2481
H5Aexists_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
2482
                        const char *obj_name, const char *attr_name, hbool_t *attr_exists, hid_t lapl_id,
2483
                        hid_t es_id)
2484
0
{
2485
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
2486
0
    void          *token     = NULL;            /* Request token for async operation        */
2487
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
2488
0
    herr_t         ret_value = SUCCEED;         /* Return value */
2489
2490
0
    FUNC_ENTER_API(FAIL)
2491
2492
    /* Set up request token pointer for asynchronous operation */
2493
0
    if (H5ES_NONE != es_id)
2494
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
2495
2496
    /* Asynchronously check if an attribute exists */
2497
0
    if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, attr_exists, lapl_id, token_ptr,
2498
0
                                       &vol_obj) < 0)
2499
0
        HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL,
2500
0
                    "can't asynchronously determine if attribute exists by name");
2501
2502
    /* If a token was created, add the token to the event set */
2503
0
    if (NULL != token)
2504
        /* clang-format off */
2505
0
        if (H5ES_insert(es_id, vol_obj->connector, token,
2506
0
                        H5ARG_TRACE9(__func__, "*s*sIui*s*s*bii", app_file, app_func, app_line, loc_id, obj_name, attr_name, attr_exists, lapl_id, es_id)) < 0)
2507
            /* clang-format on */
2508
0
            HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set");
2509
2510
0
done:
2511
0
    FUNC_LEAVE_API(ret_value)
2512
0
} /* H5Aexists_by_name_async() */