1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the files COPYING and Copyright.html. COPYING can be found at the root *
9 * of the source code distribution tree; Copyright.html can be found at the *
10 * root level of an installed copy of the electronic HDF5 document set and *
11 * is linked from the top-level documents page. It can also be found at *
12 * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
13 * access to either file, you may request a copy from help@hdfgroup.org. *
14 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
16 /****************/
17 /* Module Setup */
18 /****************/
19
20 #define H5A_PACKAGE /*suppress error about including H5Apkg */
21 #define H5O_PACKAGE /*suppress error about including H5Opkg */
22
23 /* Interface initialization */
24 #define H5_INTERFACE_INIT_FUNC H5A_init_interface
25
26
27 /***********/
28 /* Headers */
29 /***********/
30 #include "H5private.h" /* Generic Functions */
31 #include "H5Apkg.h" /* Attributes */
32 #include "H5Eprivate.h" /* Error handling */
33 #include "H5FLprivate.h" /* Free Lists */
34 #include "H5Iprivate.h" /* IDs */
35 #include "H5MMprivate.h" /* Memory management */
36 #include "H5Opkg.h" /* Object headers */
37 #include "H5Sprivate.h" /* Dataspace functions */
38 #include "H5SMprivate.h" /* Shared Object Header Messages */
39
40 /****************/
41 /* Local Macros */
42 /****************/
43
44
45 /******************/
46 /* Local Typedefs */
47 /******************/
48
49 /* Object header iterator callbacks */
50 /* Data structure for callback for locating the index by name */
51 typedef struct H5A_iter_cb1 {
52 const char *name;
53 int idx;
54 } H5A_iter_cb1;
55
56
57 /********************/
58 /* Package Typedefs */
59 /********************/
60
61
62 /********************/
63 /* Local Prototypes */
64 /********************/
65
66 static herr_t H5A_open_common(const H5G_loc_t *loc, H5A_t *attr);
67 static herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id);
68 static herr_t H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id);
69
70
71 /*********************/
72 /* Package Variables */
73 /*********************/
74
75
76 /*****************************/
77 /* Library Private Variables */
78 /*****************************/
79
80
81 /*******************/
82 /* Local Variables */
83 /*******************/
84
85 /* Declare the free lists of H5A_t */
86 H5FL_DEFINE(H5A_t);
87
88 /* Declare the free lists for H5A_shared_t's */
89 H5FL_DEFINE(H5A_shared_t);
90
91 /* Declare a free list to manage blocks of type conversion data */
92 H5FL_BLK_DEFINE(attr_buf);
93
94 /* Attribute ID class */
95 static const H5I_class_t H5I_ATTR_CLS[1] = {{
96 H5I_ATTR, /* ID class value */
97 H5I_CLASS_REUSE_IDS, /* Class flags */
98 0, /* # of reserved IDs for class */
99 (H5I_free_t)H5A_close /* Callback routine for closing objects of this class */
100 }};
101
102
103
104 /*-------------------------------------------------------------------------
105 * Function: H5A_init
106 *
107 * Purpose: Initialize the interface from some other package.
108 *
109 * Return: Success: non-negative
110 * Failure: negative
111 *
112 * Programmer: Quincey Koziol
113 * Monday, November 27, 2006
114 *
115 *-------------------------------------------------------------------------
116 */
117 herr_t
H5A_init(void)118 H5A_init(void)
119 {
120 herr_t ret_value = SUCCEED; /* Return value */
121
122 FUNC_ENTER_NOAPI(FAIL)
123 /* FUNC_ENTER() does all the work */
124
125 done:
126 FUNC_LEAVE_NOAPI(ret_value)
127 } /* end H5A_init() */
128
129
130 /*--------------------------------------------------------------------------
131 NAME
132 H5A_init_interface -- Initialize interface-specific information
133 USAGE
134 herr_t H5A_init_interface()
135
136 RETURNS
137 Non-negative on success/Negative on failure
138 DESCRIPTION
139 Initializes any interface-specific data or routines.
140
141 --------------------------------------------------------------------------*/
142 static herr_t
H5A_init_interface(void)143 H5A_init_interface(void)
144 {
145 herr_t ret_value = SUCCEED; /* Return value */
146
147 FUNC_ENTER_NOAPI_NOINIT
148
149 /*
150 * Create attribute ID type.
151 */
152 if(H5I_register_type(H5I_ATTR_CLS) < 0)
153 HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to initialize interface")
154
155 done:
156 FUNC_LEAVE_NOAPI(ret_value)
157 } /* end H5A_init_interface() */
158
159
160 /*--------------------------------------------------------------------------
161 NAME
162 H5A_term_interface
163 PURPOSE
164 Terminate various H5A objects
165 USAGE
166 void H5A_term_interface()
167 RETURNS
168 DESCRIPTION
169 Release any other resources allocated.
170 GLOBAL VARIABLES
171 COMMENTS, BUGS, ASSUMPTIONS
172 Can't report errors...
173 EXAMPLES
174 REVISION LOG
175 --------------------------------------------------------------------------*/
176 int
H5A_term_interface(void)177 H5A_term_interface(void)
178 {
179 int n = 0;
180
181 FUNC_ENTER_NOAPI_NOINIT_NOERR
182
183 if(H5_interface_initialize_g) {
184 if((n = H5I_nmembers(H5I_ATTR))>0) {
185 (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE);
186 } else {
187 /* Close deprecated interface */
188 n += H5A__term_deprec_interface();
189
190 (void)H5I_dec_type_ref(H5I_ATTR);
191 H5_interface_initialize_g = 0;
192 n = 1;
193 }
194 }
195 FUNC_LEAVE_NOAPI(n)
196 } /* H5A_term_interface() */
197
198
199 /*--------------------------------------------------------------------------
200 NAME
201 H5Acreate2
202 PURPOSE
203 Creates an attribute on an object
204 USAGE
205 hid_t H5Acreate2(loc_id, attr_name, type_id, space_id, acpl_id,
206 aapl_id)
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 (currently not used)
212 hid_t aapl_id; IN: Attribute access property list
213 RETURNS
214 Non-negative on success/Negative on failure
215
216 DESCRIPTION
217 This function creates an attribute which is attached to the object
218 specified with 'loc_id'. The name specified with 'attr_name' for
219 each attribute for an object must be unique for that object. The 'type_id'
220 and 'space_id' are created with the H5T and H5S interfaces respectively.
221 The 'aapl_id' property list is currently unused, but will be used in the
222 future for optional attribute access properties. The attribute ID returned
223 from this function must be released with H5Aclose or resource leaks will
224 develop.
225
226 --------------------------------------------------------------------------*/
227 /* ARGSUSED */
228 hid_t
H5Acreate2(hid_t loc_id,const char * attr_name,hid_t type_id,hid_t space_id,hid_t acpl_id,hid_t UNUSED aapl_id)229 H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id,
230 hid_t acpl_id, hid_t UNUSED aapl_id)
231 {
232 H5G_loc_t loc; /* Object location */
233 H5T_t *type; /* Datatype to use for attribute */
234 H5S_t *space; /* Dataspace to use for attribute */
235 hid_t ret_value; /* Return value */
236
237 FUNC_ENTER_API(FAIL)
238 H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, acpl_id, aapl_id);
239
240 /* check arguments */
241 if(H5I_ATTR == H5I_get_type(loc_id))
242 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
243 if(H5G_loc(loc_id, &loc) < 0)
244 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
245 if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR))
246 HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, FAIL, "no write intent on file")
247 if(!attr_name || !*attr_name)
248 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
249 if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
250 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type")
251 if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
252 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
253
254 /* Go do the real work for attaching the attribute to the dataset */
255 if((ret_value = H5A_create(&loc, attr_name, type, space, acpl_id, H5AC_dxpl_id)) < 0)
256 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute")
257
258 done:
259 FUNC_LEAVE_API(ret_value)
260 } /* H5Acreate2() */
261
262
263 /*--------------------------------------------------------------------------
264 NAME
265 H5Acreate_by_name
266 PURPOSE
267 Creates an attribute on an object
268 USAGE
269 hid_t H5Acreate_by_name(loc_id, obj_name, attr_name, type_id, space_id, acpl_id,
270 aapl_id, lapl_id)
271 hid_t loc_id; IN: Object (dataset or group) to be attached to
272 const char *obj_name; IN: Name of object relative to location
273 const char *attr_name; IN: Name of attribute to locate and open
274 hid_t type_id; IN: ID of datatype for attribute
275 hid_t space_id; IN: ID of dataspace for attribute
276 hid_t acpl_id; IN: ID of creation property list (currently not used)
277 hid_t aapl_id; IN: Attribute access property list
278 hid_t lapl_id; IN: Link access property list
279 RETURNS
280 Non-negative on success/Negative on failure
281
282 DESCRIPTION
283 This function creates an attribute which is attached to the object
284 specified with 'loc_id/obj_name'. The name specified with 'attr_name' for
285 each attribute for an object must be unique for that object. The 'type_id'
286 and 'space_id' are created with the H5T and H5S interfaces respectively.
287 The 'aapl_id' property list is currently unused, but will be used in the
288 future for optional attribute access properties. The attribute ID returned
289 from this function must be released with H5Aclose or resource leaks will
290 develop.
291
292 --------------------------------------------------------------------------*/
293 /* ARGSUSED */
294 hid_t
H5Acreate_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,hid_t type_id,hid_t space_id,hid_t acpl_id,hid_t UNUSED aapl_id,hid_t lapl_id)295 H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
296 hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t UNUSED aapl_id,
297 hid_t lapl_id)
298 {
299 H5G_loc_t loc; /* Object location */
300 H5G_loc_t obj_loc; /* Location used to open group */
301 H5G_name_t obj_path; /* Opened object group hier. path */
302 H5O_loc_t obj_oloc; /* Opened object object location */
303 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
304 H5T_t *type; /* Datatype to use for attribute */
305 H5S_t *space; /* Dataspace to use for attribute */
306 hid_t ret_value; /* Return value */
307
308 FUNC_ENTER_API(FAIL)
309 H5TRACE8("i", "i*s*siiiii", loc_id, obj_name, attr_name, type_id, space_id,
310 acpl_id, aapl_id, lapl_id);
311
312 /* check arguments */
313 if(H5I_ATTR == H5I_get_type(loc_id))
314 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
315 if(H5G_loc(loc_id, &loc) < 0)
316 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
317 if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR))
318 HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, FAIL, "no write intent on file")
319 if(!obj_name || !*obj_name)
320 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
321 if(!attr_name || !*attr_name)
322 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
323 if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
324 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type")
325 if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
326 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
327
328 /* Set up opened group location to fill in */
329 obj_loc.oloc = &obj_oloc;
330 obj_loc.path = &obj_path;
331 H5G_loc_reset(&obj_loc);
332
333 /* Find the object's location */
334 if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
335 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
336 loc_found = TRUE;
337
338 /* Go do the real work for attaching the attribute to the dataset */
339 if((ret_value = H5A_create(&obj_loc, attr_name, type, space, acpl_id, H5AC_dxpl_id)) < 0)
340 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute")
341
342 done:
343 /* Release resources */
344 if(loc_found && H5G_loc_free(&obj_loc) < 0)
345 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
346
347 FUNC_LEAVE_API(ret_value)
348 } /* H5Acreate_by_name() */
349
350
351 /*-------------------------------------------------------------------------
352 * Function: H5A_create
353 *
354 * Purpose:
355 * This is the guts of creating an attribute.
356 * Usage:
357 * hid_t H5A_create(ent, name, type, space)
358 * const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute
359 * const char *name; IN: Name of attribute
360 * H5T_t *type; IN: Datatype of attribute
361 * H5S_t *space; IN: Dataspace of attribute
362 * hid_t acpl_id IN: Attribute creation property list
363 *
364 * Return: Non-negative on success/Negative on failure
365 *
366 * Programmer: Quincey Koziol
367 * April 2, 1998
368 *
369 *-------------------------------------------------------------------------
370 */
371 hid_t
H5A_create(const H5G_loc_t * loc,const char * name,const H5T_t * type,const H5S_t * space,hid_t acpl_id,hid_t dxpl_id)372 H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
373 const H5S_t *space, hid_t acpl_id, hid_t dxpl_id)
374 {
375 H5A_t *attr = NULL; /* Attribute created */
376 hssize_t snelmts; /* elements in attribute */
377 size_t nelmts; /* elements in attribute */
378 htri_t tri_ret; /* htri_t return value */
379 hid_t ret_value; /* Return value */
380
381 FUNC_ENTER_NOAPI_NOINIT
382
383 /* check args */
384 HDassert(loc);
385 HDassert(name);
386 HDassert(type);
387 HDassert(space);
388
389 /* Check for existing attribute with same name */
390 /* (technically, the "attribute create" operation will fail for a duplicated
391 * name, but it's going to be hard to unwind all the special cases on
392 * failure, so just check first, for now - QAK)
393 */
394 if((tri_ret = H5O_attr_exists(loc->oloc, name, H5AC_ind_dxpl_id)) < 0)
395 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "error checking attributes")
396 else if(tri_ret > 0)
397 HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, FAIL, "attribute already exists")
398
399 /* Check if the dataspace has an extent set (or is NULL) */
400 if(!(H5S_has_extent(space)))
401 HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "dataspace extent has not been set")
402
403 /* Check if the datatype is "sensible" for use in a dataset */
404 if(H5T_is_sensible(type) != TRUE)
405 HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "datatype is not sensible")
406
407 /* Build the attribute information */
408 if(NULL == (attr = H5FL_CALLOC(H5A_t)))
409 HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed for attribute info")
410
411 if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
412 HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "can't allocate shared attr structure")
413
414 /* If the creation property list is H5P_DEFAULT, use the default character encoding */
415 if(acpl_id == H5P_DEFAULT)
416 attr->shared->encoding = H5F_DEFAULT_CSET;
417 else {
418 H5P_genplist_t *ac_plist; /* ACPL Property list */
419
420 /* Get a local copy of the attribute creation property list */
421 if(NULL == (ac_plist = (H5P_genplist_t *)H5I_object(acpl_id)))
422 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
423
424 if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0)
425 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag")
426 } /* end else */
427
428 /* Copy the attribute name */
429 attr->shared->name = H5MM_xstrdup(name);
430
431 /* Copy datatype */
432 if(NULL == (attr->shared->dt = H5T_copy(type, H5T_COPY_ALL)))
433 HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared datatype info")
434
435 /* Mark datatype as being on disk now */
436 if(H5T_set_loc(attr->shared->dt, loc->oloc->file, H5T_LOC_DISK) < 0)
437 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
438
439 /* Set the latest format for datatype, if requested */
440 if(H5F_USE_LATEST_FORMAT(loc->oloc->file))
441 if(H5T_set_latest_version(attr->shared->dt) < 0)
442 HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype")
443
444 /* Copy the dataspace for the attribute */
445 attr->shared->ds = H5S_copy(space, FALSE, TRUE);
446
447 /* Set the latest format for dataspace, if requested */
448 if(H5F_USE_LATEST_FORMAT(loc->oloc->file))
449 if(H5S_set_latest_version(attr->shared->ds) < 0)
450 HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of dataspace")
451
452 /* Copy the object header information */
453 if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
454 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
455
456 /* Deep copy of the group hierarchy path */
457 if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0)
458 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy path")
459
460 /* Check if any of the pieces should be (or are already) shared in the
461 * SOHM table
462 */
463 if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0)
464 HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed")
465 if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0)
466 HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed")
467
468 /* Check whether datatype is committed & increment ref count
469 * (to maintain ref. count incr/decr similarity with "shared message"
470 * type of datatype sharing)
471 */
472 if(H5T_committed(attr->shared->dt)) {
473 /* Increment the reference count on the shared datatype */
474 if(H5T_link(attr->shared->dt, 1, dxpl_id) < 0)
475 HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
476 } /* end if */
477
478 /* Compute the size of pieces on disk. This is either the size of the
479 * datatype and dataspace messages themselves, or the size of the "shared"
480 * messages if either or both of them are shared.
481 */
482 attr->shared->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt);
483 attr->shared->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds);
484
485 /* Get # of elements for attribute's dataspace */
486 if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
487 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
488 H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t);
489
490 HDassert(attr->shared->dt_size > 0);
491 HDassert(attr->shared->ds_size > 0);
492 attr->shared->data_size = nelmts * H5T_GET_SIZE(attr->shared->dt);
493
494 /* Hold the symbol table entry (and file) open */
495 if(H5O_open(&(attr->oloc)) < 0)
496 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
497 attr->obj_opened = TRUE;
498
499 /* Set the version to encode the attribute with */
500 if(H5A_set_version(attr->oloc.file, attr) < 0)
501 HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version")
502
503 /* Insert the attribute into the object header */
504 if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0)
505 HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header")
506
507 /* Register the new attribute and get an ID for it */
508 if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
509 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
510
511 done:
512 /* Cleanup on failure */
513 if(ret_value < 0 && attr && H5A_close(attr) < 0)
514 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
515
516 FUNC_LEAVE_NOAPI(ret_value)
517 } /* H5A_create() */
518
519
520 /*--------------------------------------------------------------------------
521 NAME
522 H5Aopen
523 PURPOSE
524 Opens an attribute for an object by looking up the attribute name
525 USAGE
526 hid_t H5Aopen(loc_id, attr_name, aapl_id)
527 hid_t loc_id; IN: Object that attribute is attached to
528 const char *attr_name; IN: Name of attribute to locate and open
529 hid_t aapl_id; IN: Attribute access property list
530 RETURNS
531 ID of attribute on success, negative on failure
532
533 DESCRIPTION
534 This function opens an existing attribute for access. The attribute
535 name specified is used to look up the corresponding attribute for the
536 object. The attribute ID returned from this function must be released with
537 H5Aclose or resource leaks will develop.
538 --------------------------------------------------------------------------*/
539 hid_t
H5Aopen(hid_t loc_id,const char * attr_name,hid_t UNUSED aapl_id)540 H5Aopen(hid_t loc_id, const char *attr_name, hid_t UNUSED aapl_id)
541 {
542 H5G_loc_t loc; /* Object location */
543 H5A_t *attr = NULL; /* Attribute opened */
544 hid_t ret_value;
545
546 FUNC_ENTER_API(FAIL)
547 H5TRACE3("i", "i*si", loc_id, attr_name, aapl_id);
548
549 /* check arguments */
550 if(H5I_ATTR == H5I_get_type(loc_id))
551 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
552 if(H5G_loc(loc_id, &loc) < 0)
553 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
554 if(!attr_name || !*attr_name)
555 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
556
557 /* Read in attribute from object header */
558 if(NULL == (attr = H5O_attr_open_by_name(loc.oloc, attr_name, H5AC_ind_dxpl_id)))
559 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header for attribute: '%s'", attr_name)
560
561 /* Finish initializing attribute */
562 if(H5A_open_common(&loc, attr) < 0)
563 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize attribute")
564
565 /* Register the attribute and get an ID for it */
566 if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
567 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
568
569 done:
570 /* Cleanup on failure */
571 if(ret_value < 0)
572 if(attr && H5A_close(attr) < 0)
573 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
574
575 FUNC_LEAVE_API(ret_value)
576 } /* H5Aopen() */
577
578
579 /*--------------------------------------------------------------------------
580 NAME
581 H5Aopen_by_name
582 PURPOSE
583 Opens an attribute for an object by looking up the attribute name
584 USAGE
585 hid_t H5Aopen_by_name(loc_id, obj_name, attr_name, aapl_id, lapl_id)
586 hid_t loc_id; IN: Object that attribute is attached to
587 const char *obj_name; IN: Name of object relative to location
588 const char *attr_name; IN: Name of attribute to locate and open
589 hid_t aapl_id; IN: Attribute access property list
590 hid_t lapl_id; IN: Link access property list
591 RETURNS
592 ID of attribute on success, negative on failure
593
594 DESCRIPTION
595 This function opens an existing attribute for access. The attribute
596 name specified is used to look up the corresponding attribute for the
597 object. The attribute ID returned from this function must be released with
598 H5Aclose or resource leaks will develop.
599 --------------------------------------------------------------------------*/
600 hid_t
H5Aopen_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,hid_t UNUSED aapl_id,hid_t lapl_id)601 H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
602 hid_t UNUSED aapl_id, hid_t lapl_id)
603 {
604 H5G_loc_t loc; /* Object location */
605 H5A_t *attr = NULL; /* Attribute opened */
606 hid_t ret_value;
607
608 FUNC_ENTER_API(FAIL)
609 H5TRACE5("i", "i*s*sii", loc_id, obj_name, attr_name, aapl_id, lapl_id);
610
611 /* check arguments */
612 if(H5I_ATTR == H5I_get_type(loc_id))
613 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
614 if(H5G_loc(loc_id, &loc) < 0)
615 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
616 if(!obj_name || !*obj_name)
617 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
618 if(!attr_name || !*attr_name)
619 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
620 if(H5P_DEFAULT == lapl_id)
621 lapl_id = H5P_LINK_ACCESS_DEFAULT;
622 else
623 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
624 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
625
626 /* Open the attribute on the object header */
627 if(NULL == (attr = H5A_open_by_name(&loc, obj_name, attr_name, lapl_id, H5AC_ind_dxpl_id)))
628 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
629
630 /* Register the attribute and get an ID for it */
631 if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
632 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
633
634 done:
635 /* Cleanup on failure */
636 if(ret_value < 0)
637 if(attr && H5A_close(attr) < 0)
638 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
639
640 FUNC_LEAVE_API(ret_value)
641 } /* H5Aopen_by_name() */
642
643
644 /*--------------------------------------------------------------------------
645 NAME
646 H5Aopen_by_idx
647 PURPOSE
648 Opens the n'th attribute for an object, according to the order within
649 an index
650 USAGE
651 hid_t H5Aopen_by_idx(loc_id, obj_ame, idx_type, order, n, aapl_id, lapl_id)
652 hid_t loc_id; IN: Object that attribute is attached to
653 const char *obj_name; IN: Name of object relative to location
654 H5_index_t idx_type; IN: Type of index to use
655 H5_iter_order_t order; IN: Order to iterate over index
656 hsize_t n; IN: Index (0-based) attribute to open
657 hid_t aapl_id; IN: Attribute access property list
658 hid_t lapl_id; IN: Link access property list
659 RETURNS
660 ID of attribute on success, negative on failure
661
662 DESCRIPTION
663 This function opens an existing attribute for access. The attribute
664 index specified is used to look up the corresponding attribute for the
665 object. The attribute ID returned from this function must be released with
666 H5Aclose or resource leaks will develop.
667 --------------------------------------------------------------------------*/
668 hid_t
H5Aopen_by_idx(hid_t loc_id,const char * obj_name,H5_index_t idx_type,H5_iter_order_t order,hsize_t n,hid_t UNUSED aapl_id,hid_t lapl_id)669 H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
670 H5_iter_order_t order, hsize_t n, hid_t UNUSED aapl_id, hid_t lapl_id)
671 {
672 H5A_t *attr = NULL; /* Attribute opened */
673 H5G_loc_t loc; /* Object location */
674 hid_t ret_value; /* Return value */
675
676 FUNC_ENTER_API(FAIL)
677 H5TRACE7("i", "i*sIiIohii", loc_id, obj_name, idx_type, order, n, aapl_id,
678 lapl_id);
679
680 /* check arguments */
681 if(H5I_ATTR == H5I_get_type(loc_id))
682 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
683 if(H5G_loc(loc_id, &loc) < 0)
684 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
685 if(!obj_name || !*obj_name)
686 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
687 if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
688 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
689 if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
690 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
691 if(H5P_DEFAULT == lapl_id)
692 lapl_id = H5P_LINK_ACCESS_DEFAULT;
693 else
694 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
695 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
696
697 /* Open the attribute in the object header */
698 if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id)))
699 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open attribute")
700
701 /* Register the attribute and get an ID for it */
702 if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
703 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
704
705 done:
706 /* Cleanup on failure */
707 if(ret_value < 0)
708 if(attr && H5A_close(attr) < 0)
709 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
710
711 FUNC_LEAVE_API(ret_value)
712 } /* H5Aopen_by_idx() */
713
714
715 /*-------------------------------------------------------------------------
716 * Function: H5A_open_common
717 *
718 * Purpose:
719 * Finishes initializing an attributes the open
720 *
721 * Usage:
722 * herr_t H5A_open_common(loc, name, dxpl_id)
723 * const H5G_loc_t *loc; IN: Pointer to group location for object
724 * H5A_t *attr; IN/OUT: Pointer to attribute to initialize
725 *
726 * Return: Non-negative on success/Negative on failure
727 *
728 * Programmer: Quincey Koziol
729 * December 18, 2006
730 *
731 *-------------------------------------------------------------------------
732 */
733 static herr_t
H5A_open_common(const H5G_loc_t * loc,H5A_t * attr)734 H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
735 {
736 herr_t ret_value = SUCCEED; /* Return value */
737
738 FUNC_ENTER_NOAPI_NOINIT
739
740 /* check args */
741 HDassert(loc);
742 HDassert(attr);
743
744 #if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG)
745 /* Clear object location */
746 if(H5O_loc_reset(&(attr->oloc)) < 0)
747 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location")
748 #endif /* H5_USING_MEMCHECKER */
749
750 /* Free any previous group hier. path */
751 if(H5G_name_free(&(attr->path)) < 0)
752 HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
753
754 /* Deep copy of the symbol table entry */
755 if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
756 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
757
758 /* Deep copy of the group hier. path */
759 if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0)
760 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry")
761
762 /* Hold the symbol table entry (and file) open */
763 if(H5O_open(&(attr->oloc)) < 0)
764 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
765 attr->obj_opened = TRUE;
766
767 done:
768 FUNC_LEAVE_NOAPI(ret_value)
769 } /* H5A_open_common() */
770
771
772 /*-------------------------------------------------------------------------
773 * Function: H5A_open_by_idx
774 *
775 * Purpose: Open an attribute according to its index order
776 *
777 * Return: Non-negative on success/Negative on failure
778 *
779 * Programmer: Quincey Koziol
780 * April 2, 1998
781 *
782 *-------------------------------------------------------------------------
783 */
784 H5A_t *
H5A_open_by_idx(const H5G_loc_t * loc,const char * obj_name,H5_index_t idx_type,H5_iter_order_t order,hsize_t n,hid_t lapl_id,hid_t dxpl_id)785 H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
786 H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t dxpl_id)
787 {
788 H5G_loc_t obj_loc; /* Location used to open group */
789 H5G_name_t obj_path; /* Opened object group hier. path */
790 H5O_loc_t obj_oloc; /* Opened object object location */
791 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
792 H5A_t *attr = NULL; /* Attribute from object header */
793 H5A_t *ret_value; /* Return value */
794
795 FUNC_ENTER_NOAPI_NOINIT
796
797 /* check args */
798 HDassert(loc);
799 HDassert(obj_name);
800
801 /* Set up opened group location to fill in */
802 obj_loc.oloc = &obj_oloc;
803 obj_loc.path = &obj_path;
804 H5G_loc_reset(&obj_loc);
805
806 /* Find the object's location */
807 if(H5G_loc_find(loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0)
808 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found")
809 loc_found = TRUE;
810
811 /* Read in attribute from object header */
812 if(NULL == (attr = H5O_attr_open_by_idx(obj_loc.oloc, idx_type, order, n, dxpl_id)))
813 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to load attribute info from object header")
814
815 /* Finish initializing attribute */
816 if(H5A_open_common(&obj_loc, attr) < 0)
817 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute")
818
819 /* Set return value */
820 ret_value = attr;
821
822 done:
823 /* Release resources */
824 if(loc_found && H5G_loc_free(&obj_loc) < 0)
825 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location")
826
827 /* Cleanup on failure */
828 if(ret_value == NULL)
829 if(attr && H5A_close(attr) < 0)
830 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
831
832 FUNC_LEAVE_NOAPI(ret_value)
833 } /* H5A_open_by_idx() */
834
835
836 /*-------------------------------------------------------------------------
837 * Function: H5A_open_by_name
838 *
839 * Purpose: Open an attribute in an object header, according to it's name
840 *
841 * Return: Non-negative on success/Negative on failure
842 *
843 * Programmer: Quincey Koziol
844 * December 11, 2006
845 *
846 *-------------------------------------------------------------------------
847 */
848 H5A_t *
H5A_open_by_name(const H5G_loc_t * loc,const char * obj_name,const char * attr_name,hid_t lapl_id,hid_t dxpl_id)849 H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name,
850 hid_t lapl_id, hid_t dxpl_id)
851 {
852 H5G_loc_t obj_loc; /* Location used to open group */
853 H5G_name_t obj_path; /* Opened object group hier. path */
854 H5O_loc_t obj_oloc; /* Opened object object location */
855 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
856 H5A_t *attr = NULL; /* Attribute from object header */
857 H5A_t *ret_value; /* Return value */
858
859 FUNC_ENTER_NOAPI(NULL)
860
861 /* check args */
862 HDassert(loc);
863 HDassert(obj_name);
864 HDassert(attr_name);
865
866 /* Set up opened group location to fill in */
867 obj_loc.oloc = &obj_oloc;
868 obj_loc.path = &obj_path;
869 H5G_loc_reset(&obj_loc);
870
871 /* Find the object's location */
872 if(H5G_loc_find(loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0)
873 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found")
874 loc_found = TRUE;
875
876 /* Read in attribute from object header */
877 if(NULL == (attr = H5O_attr_open_by_name(obj_loc.oloc, attr_name, dxpl_id)))
878 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header")
879
880 /* Finish initializing attribute */
881 if(H5A_open_common(loc, attr) < 0)
882 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute")
883
884 /* Set return value */
885 ret_value = attr;
886
887 done:
888 /* Release resources */
889 if(loc_found && H5G_loc_free(&obj_loc) < 0)
890 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location")
891
892 /* Cleanup on failure */
893 if(ret_value == NULL)
894 if(attr && H5A_close(attr) < 0)
895 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
896
897 FUNC_LEAVE_NOAPI(ret_value)
898 } /* H5A_open_by_name() */
899
900
901 /*--------------------------------------------------------------------------
902 NAME
903 H5Awrite
904 PURPOSE
905 Write out data to an attribute
906 USAGE
907 herr_t H5Awrite (attr_id, dtype_id, buf)
908 hid_t attr_id; IN: Attribute to write
909 hid_t dtype_id; IN: Memory datatype of buffer
910 const void *buf; IN: Buffer of data to write
911 RETURNS
912 Non-negative on success/Negative on failure
913
914 DESCRIPTION
915 This function writes a complete attribute to disk.
916 --------------------------------------------------------------------------*/
917 herr_t
H5Awrite(hid_t attr_id,hid_t dtype_id,const void * buf)918 H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf)
919 {
920 H5A_t *attr; /* Attribute object for ID */
921 H5T_t *mem_type; /* Memory datatype */
922 herr_t ret_value; /* Return value */
923
924 FUNC_ENTER_API(FAIL)
925 H5TRACE3("e", "ii*x", attr_id, dtype_id, buf);
926
927 /* check arguments */
928 if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
929 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
930 if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
931 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
932 if(NULL == buf)
933 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
934
935 /* Go write the actual data to the attribute */
936 if((ret_value = H5A_write(attr, mem_type, buf, H5AC_dxpl_id)) < 0)
937 HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
938
939 done:
940 FUNC_LEAVE_API(ret_value)
941 } /* H5Awrite() */
942
943
944 /*--------------------------------------------------------------------------
945 NAME
946 H5A_write
947 PURPOSE
948 Actually write out data to an attribute
949 USAGE
950 herr_t H5A_write (attr, mem_type, buf)
951 H5A_t *attr; IN: Attribute to write
952 const H5T_t *mem_type; IN: Memory datatype of buffer
953 const void *buf; IN: Buffer of data to write
954 RETURNS
955 Non-negative on success/Negative on failure
956
957 DESCRIPTION
958 This function writes a complete attribute to disk.
959 --------------------------------------------------------------------------*/
960 static herr_t
H5A_write(H5A_t * attr,const H5T_t * mem_type,const void * buf,hid_t dxpl_id)961 H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
962 {
963 uint8_t *tconv_buf = NULL; /* datatype conv buffer */
964 hbool_t tconv_owned = FALSE; /* Whether the datatype conv buffer is owned by attribute */
965 uint8_t *bkg_buf = NULL; /* temp conversion buffer */
966 hssize_t snelmts; /* elements in attribute */
967 size_t nelmts; /* elements in attribute */
968 H5T_path_t *tpath = NULL; /* conversion information*/
969 hid_t src_id = -1, dst_id = -1;/* temporary type atoms */
970 size_t src_type_size; /* size of source type */
971 size_t dst_type_size; /* size of destination type*/
972 size_t buf_size; /* desired buffer size */
973 herr_t ret_value = SUCCEED;
974
975 FUNC_ENTER_NOAPI_NOINIT
976
977 HDassert(attr);
978 HDassert(mem_type);
979 HDassert(buf);
980
981 /* Get # of elements for attribute's dataspace */
982 if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
983 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
984 H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t);
985
986 /* If there's actually data elements for the attribute, make a copy of the data passed in */
987 if(nelmts > 0) {
988 /* Get the memory and file datatype sizes */
989 src_type_size = H5T_GET_SIZE(mem_type);
990 dst_type_size = H5T_GET_SIZE(attr->shared->dt);
991
992 /* Convert memory buffer into disk buffer */
993 /* Set up type conversion function */
994 if(NULL == (tpath = H5T_path_find(mem_type, attr->shared->dt, NULL, NULL, dxpl_id, FALSE)))
995 HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
996
997 /* Check for type conversion required */
998 if(!H5T_path_noop(tpath)) {
999 if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0 ||
1000 (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0)
1001 HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
1002
1003 /* Get the maximum buffer size needed and allocate it */
1004 buf_size = nelmts * MAX(src_type_size, dst_type_size);
1005 if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
1006 HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed")
1007 if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
1008 HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed")
1009
1010 /* Copy the user's data into the buffer for conversion */
1011 HDmemcpy(tconv_buf, buf, (src_type_size * nelmts));
1012
1013 /* Perform datatype conversion */
1014 if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
1015 HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
1016
1017 /* Free the previous attribute data buffer, if there is one */
1018 if(attr->shared->data)
1019 attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data);
1020
1021 /* Set the pointer to the attribute data to the converted information */
1022 attr->shared->data = tconv_buf;
1023 tconv_owned = TRUE;
1024 } /* end if */
1025 /* No type conversion necessary */
1026 else {
1027 HDassert(dst_type_size == src_type_size);
1028
1029 /* Allocate the attribute buffer, if there isn't one */
1030 if(attr->shared->data == NULL)
1031 if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts)))
1032 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
1033
1034 /* Copy the attribute data into the user's buffer */
1035 HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts));
1036 } /* end else */
1037
1038 /* Modify the attribute in the object header */
1039 if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0)
1040 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute")
1041 } /* end if */
1042
1043 done:
1044 /* Release resources */
1045 if(src_id >= 0 && H5I_dec_ref(src_id) < 0)
1046 HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
1047 if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0)
1048 HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
1049 if(tconv_buf && !tconv_owned)
1050 tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf);
1051 if(bkg_buf)
1052 bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf);
1053
1054 FUNC_LEAVE_NOAPI(ret_value)
1055 } /* H5A_write() */
1056
1057
1058 /*--------------------------------------------------------------------------
1059 NAME
1060 H5Aread
1061 PURPOSE
1062 Read in data from an attribute
1063 USAGE
1064 herr_t H5Aread (attr_id, dtype_id, buf)
1065 hid_t attr_id; IN: Attribute to read
1066 hid_t dtype_id; IN: Memory datatype of buffer
1067 void *buf; IN: Buffer for data to read
1068 RETURNS
1069 Non-negative on success/Negative on failure
1070
1071 DESCRIPTION
1072 This function reads a complete attribute from disk.
1073 --------------------------------------------------------------------------*/
1074 herr_t
H5Aread(hid_t attr_id,hid_t dtype_id,void * buf)1075 H5Aread(hid_t attr_id, hid_t dtype_id, void *buf)
1076 {
1077 H5A_t *attr; /* Attribute object for ID */
1078 H5T_t *mem_type; /* Memory datatype */
1079 herr_t ret_value; /* Return value */
1080
1081 FUNC_ENTER_API(FAIL)
1082 H5TRACE3("e", "ii*x", attr_id, dtype_id, buf);
1083
1084 /* check arguments */
1085 if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1086 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
1087 if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
1088 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
1089 if(NULL == buf)
1090 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
1091
1092 /* Go write the actual data to the attribute */
1093 if((ret_value = H5A_read(attr, mem_type, buf, H5AC_dxpl_id)) < 0)
1094 HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute")
1095
1096 done:
1097 FUNC_LEAVE_API(ret_value)
1098 } /* H5Aread() */
1099
1100
1101 /*--------------------------------------------------------------------------
1102 NAME
1103 H5A_read
1104 PURPOSE
1105 Actually read in data from an attribute
1106 USAGE
1107 herr_t H5A_read (attr, mem_type, buf)
1108 H5A_t *attr; IN: Attribute to read
1109 const H5T_t *mem_type; IN: Memory datatype of buffer
1110 void *buf; IN: Buffer for data to read
1111 RETURNS
1112 Non-negative on success/Negative on failure
1113
1114 DESCRIPTION
1115 This function reads a complete attribute from disk.
1116 --------------------------------------------------------------------------*/
1117 static herr_t
H5A_read(const H5A_t * attr,const H5T_t * mem_type,void * buf,hid_t dxpl_id)1118 H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
1119 {
1120 uint8_t *tconv_buf = NULL; /* datatype conv buffer*/
1121 uint8_t *bkg_buf = NULL; /* background buffer */
1122 hssize_t snelmts; /* elements in attribute */
1123 size_t nelmts; /* elements in attribute*/
1124 H5T_path_t *tpath = NULL; /* type conversion info */
1125 hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/
1126 size_t src_type_size; /* size of source type */
1127 size_t dst_type_size; /* size of destination type */
1128 size_t buf_size; /* desired buffer size */
1129 herr_t ret_value = SUCCEED;
1130
1131 FUNC_ENTER_NOAPI_NOINIT
1132
1133 HDassert(attr);
1134 HDassert(mem_type);
1135 HDassert(buf);
1136
1137 /* Create buffer for data to store on disk */
1138 if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
1139 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
1140 H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t);
1141
1142 if(nelmts > 0) {
1143 /* Get the memory and file datatype sizes */
1144 src_type_size = H5T_GET_SIZE(attr->shared->dt);
1145 dst_type_size = H5T_GET_SIZE(mem_type);
1146
1147 /* Check if the attribute has any data yet, if not, fill with zeroes */
1148 if(attr->obj_opened && !attr->shared->data)
1149 HDmemset(buf, 0, (dst_type_size * nelmts));
1150 else { /* Attribute exists and has a value */
1151 /* Convert memory buffer into disk buffer */
1152 /* Set up type conversion function */
1153 if(NULL == (tpath = H5T_path_find(attr->shared->dt, mem_type, NULL, NULL, dxpl_id, FALSE)))
1154 HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
1155
1156 /* Check for type conversion required */
1157 if(!H5T_path_noop(tpath)) {
1158 if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0 ||
1159 (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0)
1160 HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
1161
1162 /* Get the maximum buffer size needed and allocate it */
1163 buf_size = nelmts * MAX(src_type_size, dst_type_size);
1164 if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
1165 HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
1166 if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
1167 HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
1168
1169 /* Copy the attribute data into the buffer for conversion */
1170 HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts));
1171
1172 /* Perform datatype conversion. */
1173 if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
1174 HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
1175
1176 /* Copy the converted data into the user's buffer */
1177 HDmemcpy(buf, tconv_buf, (dst_type_size * nelmts));
1178 } /* end if */
1179 /* No type conversion necessary */
1180 else {
1181 HDassert(dst_type_size == src_type_size);
1182
1183 /* Copy the attribute data into the user's buffer */
1184 HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts));
1185 } /* end else */
1186 } /* end else */
1187 } /* end if */
1188
1189 done:
1190 /* Release resources */
1191 if(src_id >= 0 && H5I_dec_ref(src_id) < 0)
1192 HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
1193 if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0)
1194 HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
1195 if(tconv_buf)
1196 tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf);
1197 if(bkg_buf)
1198 bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf);
1199
1200 FUNC_LEAVE_NOAPI(ret_value)
1201 } /* H5A_read() */
1202
1203
1204 /*--------------------------------------------------------------------------
1205 NAME
1206 H5Aget_space
1207 PURPOSE
1208 Gets a copy of the dataspace for an attribute
1209 USAGE
1210 hid_t H5Aget_space (attr_id)
1211 hid_t attr_id; IN: Attribute to get dataspace of
1212 RETURNS
1213 A dataspace ID on success, negative on failure
1214
1215 DESCRIPTION
1216 This function retrieves a copy of the dataspace for an attribute.
1217 The dataspace ID returned from this function must be released with H5Sclose
1218 or resource leaks will develop.
1219 --------------------------------------------------------------------------*/
1220 hid_t
H5Aget_space(hid_t attr_id)1221 H5Aget_space(hid_t attr_id)
1222 {
1223 H5A_t *attr; /* Attribute object for ID */
1224 H5S_t *ds = NULL; /* Copy of dataspace for attribute */
1225 hid_t ret_value;
1226
1227 FUNC_ENTER_API(FAIL)
1228 H5TRACE1("i", "i", attr_id);
1229
1230 /* check arguments */
1231 if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1232 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
1233
1234 /* Copy the attribute's dataspace */
1235 if(NULL == (ds = H5S_copy(attr->shared->ds, FALSE, TRUE)))
1236 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace")
1237
1238 /* Atomize */
1239 if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0)
1240 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
1241
1242 done:
1243 if(ret_value < 0 && ds)
1244 (void)H5S_close(ds);
1245
1246 FUNC_LEAVE_API(ret_value)
1247 } /* H5Aget_space() */
1248
1249
1250 /*--------------------------------------------------------------------------
1251 NAME
1252 H5Aget_type
1253 PURPOSE
1254 Gets a copy of the datatype for an attribute
1255 USAGE
1256 hid_t H5Aget_type (attr_id)
1257 hid_t attr_id; IN: Attribute to get datatype of
1258 RETURNS
1259 A datatype ID on success, negative on failure
1260
1261 DESCRIPTION
1262 This function retrieves a copy of the datatype for an attribute.
1263 The datatype ID returned from this function must be released with H5Tclose
1264 or resource leaks will develop.
1265 --------------------------------------------------------------------------*/
1266 hid_t
H5Aget_type(hid_t attr_id)1267 H5Aget_type(hid_t attr_id)
1268 {
1269 H5A_t *attr; /* Attribute object for ID */
1270 H5T_t *dt = NULL; /* Copy of attribute's datatype */
1271 hid_t ret_value; /* Return value */
1272
1273 FUNC_ENTER_API(FAIL)
1274 H5TRACE1("i", "i", attr_id);
1275
1276 /* check arguments */
1277 if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1278 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
1279
1280 /* Patch the datatype's "top level" file pointer */
1281 if(H5T_patch_file(attr->shared->dt, attr->oloc.file) < 0)
1282 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer")
1283
1284 /*
1285 * Copy the attribute's datatype. If the type is a named type then
1286 * reopen the type before returning it to the user. Make the type
1287 * read-only.
1288 */
1289 if(NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN)))
1290 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype")
1291
1292 /* Mark any datatypes as being in memory now */
1293 if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0)
1294 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
1295
1296 /* Lock copied type */
1297 if(H5T_lock(dt, FALSE) < 0)
1298 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
1299
1300 /* Atomize */
1301 if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
1302 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype ID")
1303
1304 done:
1305 if(ret_value < 0) {
1306 if(dt && H5T_close(dt) < 0)
1307 HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release datatype")
1308 } /* end if */
1309
1310 FUNC_LEAVE_API(ret_value)
1311 } /* H5Aget_type() */
1312
1313
1314 /*--------------------------------------------------------------------------
1315 NAME
1316 H5Aget_create_plist
1317 PURPOSE
1318 Gets a copy of the creation property list for an attribute
1319 USAGE
1320 hssize_t H5Aget_create_plist (attr_id, buf_size, buf)
1321 hid_t attr_id; IN: Attribute to get name of
1322 RETURNS
1323 This function returns the ID of a copy of the attribute's creation
1324 property list, or negative on failure.
1325
1326 ERRORS
1327
1328 DESCRIPTION
1329 This function returns a copy of the creation property list for
1330 an attribute. The resulting ID must be closed with H5Pclose() or
1331 resource leaks will occur.
1332 --------------------------------------------------------------------------*/
1333 hid_t
H5Aget_create_plist(hid_t attr_id)1334 H5Aget_create_plist(hid_t attr_id)
1335 {
1336 H5A_t *attr; /* Attribute object for ID */
1337 H5P_genplist_t *plist; /* Default property list */
1338 hid_t new_plist_id; /* ID of ACPL to return */
1339 H5P_genplist_t *new_plist; /* ACPL to return */
1340 hid_t ret_value;
1341
1342 FUNC_ENTER_API(FAIL)
1343 H5TRACE1("i", "i", attr_id);
1344
1345 HDassert(H5P_LST_ATTRIBUTE_CREATE_g != -1);
1346
1347 /* Get attribute and default attribute creation property list*/
1348 if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1349 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
1350 if(NULL == (plist = (H5P_genplist_t *)H5I_object(H5P_LST_ATTRIBUTE_CREATE_g)))
1351 HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default ACPL")
1352
1353 /* Create the property list object to return */
1354 if((new_plist_id = H5P_copy_plist(plist, TRUE)) < 0)
1355 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties")
1356 if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_plist_id)))
1357 HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list")
1358
1359 /* Set the character encoding on the new property list */
1360 if(H5P_set(new_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0)
1361 HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding")
1362
1363 ret_value = new_plist_id;
1364
1365 done:
1366 FUNC_LEAVE_API(ret_value)
1367 } /* end H5Aget_create_plist() */
1368
1369
1370 /*--------------------------------------------------------------------------
1371 NAME
1372 H5Aget_name
1373 PURPOSE
1374 Gets a copy of the name for an attribute
1375 USAGE
1376 hssize_t H5Aget_name (attr_id, buf_size, buf)
1377 hid_t attr_id; IN: Attribute to get name of
1378 size_t buf_size; IN: The size of the buffer to store the string in.
1379 char *buf; IN: Buffer to store name in
1380 RETURNS
1381 This function returns the length of the attribute's name (which may be
1382 longer than 'buf_size') on success or negative for failure.
1383
1384 DESCRIPTION
1385 This function retrieves the name of an attribute for an attribute ID.
1386 Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string
1387 terminator. If the name of the attribute is longer than 'buf_size'-1,
1388 the string terminator is stored in the last position of the buffer to
1389 properly terminate the string.
1390 --------------------------------------------------------------------------*/
1391 ssize_t
H5Aget_name(hid_t attr_id,size_t buf_size,char * buf)1392 H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
1393 {
1394 H5A_t *my_attr; /* Attribute object for ID */
1395 ssize_t ret_value;
1396
1397 FUNC_ENTER_API(FAIL)
1398 H5TRACE3("Zs", "iz*s", attr_id, buf_size, buf);
1399
1400 /* check arguments */
1401 if(NULL == (my_attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1402 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
1403 if(!buf && buf_size)
1404 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
1405
1406 /* Call private function in turn */
1407 if(0 > (ret_value = H5A_get_name(my_attr, buf_size, buf)))
1408 HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name")
1409
1410 done:
1411 FUNC_LEAVE_API(ret_value)
1412 } /* H5Aget_name() */
1413
1414
1415 /*--------------------------------------------------------------------------
1416 NAME
1417 H5A_get_name
1418 PURPOSE
1419 Private function for H5Aget_name. Gets a copy of the name for an
1420 attribute
1421 RETURNS
1422 This function returns the length of the attribute's name (which may be
1423 longer than 'buf_size') on success or negative for failure.
1424 DESCRIPTION
1425 This function retrieves the name of an attribute for an attribute ID.
1426 Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string
1427 terminator. If the name of the attribute is longer than 'buf_size'-1,
1428 the string terminator is stored in the last position of the buffer to
1429 properly terminate the string.
1430 --------------------------------------------------------------------------*/
1431 ssize_t
H5A_get_name(H5A_t * attr,size_t buf_size,char * buf)1432 H5A_get_name(H5A_t *attr, size_t buf_size, char *buf)
1433 {
1434 size_t copy_len, nbytes;
1435 ssize_t ret_value;
1436
1437 FUNC_ENTER_NOAPI(FAIL)
1438
1439 /* get the real attribute length */
1440 nbytes = HDstrlen(attr->shared->name);
1441 HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/
1442
1443 /* compute the string length which will fit into the user's buffer */
1444 copy_len = MIN(buf_size - 1, nbytes);
1445
1446 /* Copy all/some of the name */
1447 if(buf && copy_len > 0) {
1448 HDmemcpy(buf, attr->shared->name, copy_len);
1449
1450 /* Terminate the string */
1451 buf[copy_len]='\0';
1452 } /* end if */
1453
1454 /* Set return value */
1455 ret_value = (ssize_t)nbytes;
1456
1457 done:
1458 FUNC_LEAVE_NOAPI(ret_value)
1459 } /* H5A_get_name() */
1460
1461
1462 /*-------------------------------------------------------------------------
1463 * Function: H5Aget_name_by_idx
1464 *
1465 * Purpose: Retrieve name of an attribute, according to the
1466 * order within an index.
1467 *
1468 * Same pattern of behavior as H5Iget_name.
1469 *
1470 * Return: Success: Non-negative length of name, with information
1471 * in NAME buffer
1472 * Failure: Negative
1473 *
1474 * Programmer: Quincey Koziol
1475 * February 8, 2007
1476 *
1477 *-------------------------------------------------------------------------
1478 */
1479 ssize_t
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,char * name,size_t size,hid_t lapl_id)1480 H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
1481 H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size,
1482 hid_t lapl_id)
1483 {
1484 H5G_loc_t loc; /* Object location */
1485 H5A_t *attr = NULL; /* Attribute object for name */
1486 ssize_t ret_value; /* Return value */
1487
1488 FUNC_ENTER_API(FAIL)
1489 H5TRACE8("Zs", "i*sIiIohxzi", loc_id, obj_name, idx_type, order, n, name, size,
1490 lapl_id);
1491
1492 /* Check args */
1493 if(H5I_ATTR == H5I_get_type(loc_id))
1494 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1495 if(H5G_loc(loc_id, &loc) < 0)
1496 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1497 if(!obj_name || !*obj_name)
1498 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
1499 if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1500 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
1501 if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1502 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
1503 if(H5P_DEFAULT == lapl_id)
1504 lapl_id = H5P_LINK_ACCESS_DEFAULT;
1505 else
1506 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1507 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1508
1509 /* Open the attribute on the object header */
1510 if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id)))
1511 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
1512
1513 /* Get the length of the name */
1514 ret_value = (ssize_t)HDstrlen(attr->shared->name);
1515
1516 /* Copy the name into the user's buffer, if given */
1517 if(name) {
1518 HDstrncpy(name, attr->shared->name, MIN((size_t)(ret_value + 1), size));
1519 if((size_t)ret_value >= size)
1520 name[size - 1]='\0';
1521 } /* end if */
1522
1523 done:
1524 /* Release resources */
1525 if(attr && H5A_close(attr) < 0)
1526 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
1527
1528 FUNC_LEAVE_API(ret_value)
1529 } /* end H5Aget_name_by_idx() */
1530
1531
1532 /*-------------------------------------------------------------------------
1533 * Function: H5Aget_storage_size
1534 *
1535 * Purpose: Returns the amount of storage size that is required for this
1536 * attribute.
1537 *
1538 * Return: Success: The amount of storage size allocated for the
1539 * attribute. The return value may be zero
1540 * if no data has been stored.
1541 *
1542 * Failure: Zero
1543 *
1544 * Programmer: Raymond Lu
1545 * October 23, 2002
1546 *
1547 *-------------------------------------------------------------------------
1548 */
1549 hsize_t
H5Aget_storage_size(hid_t attr_id)1550 H5Aget_storage_size(hid_t attr_id)
1551 {
1552 H5A_t *attr; /* Attribute object for ID */
1553 hsize_t ret_value; /* Return value */
1554
1555 FUNC_ENTER_API(0)
1556 H5TRACE1("h", "i", attr_id);
1557
1558 /* Check args */
1559 if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1560 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute")
1561
1562 /* Set return value */
1563 ret_value = attr->shared->data_size;
1564
1565 done:
1566 FUNC_LEAVE_API(ret_value)
1567 } /* end H5Aget_storage_size() */
1568
1569
1570 /*-------------------------------------------------------------------------
1571 * Function: H5Aget_info
1572 *
1573 * Purpose: Retrieve information about an attribute.
1574 *
1575 * Return: Success: Non-negative
1576 * Failure: Negative
1577 *
1578 * Programmer: Quincey Koziol
1579 * February 6, 2007
1580 *
1581 *-------------------------------------------------------------------------
1582 */
1583 herr_t
H5Aget_info(hid_t attr_id,H5A_info_t * ainfo)1584 H5Aget_info(hid_t attr_id, H5A_info_t *ainfo)
1585 {
1586 H5A_t *attr; /* Attribute object for name */
1587 herr_t ret_value = SUCCEED; /* Return value */
1588
1589 FUNC_ENTER_API(FAIL)
1590 H5TRACE2("e", "i*x", attr_id, ainfo);
1591
1592 /* Check args */
1593 if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
1594 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
1595
1596 /* Get the attribute information */
1597 if(H5A_get_info(attr, ainfo) < 0)
1598 HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
1599
1600 done:
1601 FUNC_LEAVE_API(ret_value)
1602 } /* end H5Aget_info() */
1603
1604
1605 /*-------------------------------------------------------------------------
1606 * Function: H5Aget_info_by_name
1607 *
1608 * Purpose: Retrieve information about an attribute by name.
1609 *
1610 * Return: Success: Non-negative
1611 * Failure: Negative
1612 *
1613 * Programmer: Quincey Koziol
1614 * February 6, 2007
1615 *
1616 *-------------------------------------------------------------------------
1617 */
1618 herr_t
H5Aget_info_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,H5A_info_t * ainfo,hid_t lapl_id)1619 H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
1620 H5A_info_t *ainfo, hid_t lapl_id)
1621 {
1622 H5G_loc_t loc; /* Object location */
1623 H5A_t *attr = NULL; /* Attribute object for name */
1624 herr_t ret_value = SUCCEED; /* Return value */
1625
1626 FUNC_ENTER_API(FAIL)
1627 H5TRACE5("e", "i*s*s*xi", loc_id, obj_name, attr_name, ainfo, lapl_id);
1628
1629 /* Check args */
1630 if(H5I_ATTR == H5I_get_type(loc_id))
1631 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1632 if(H5G_loc(loc_id, &loc) < 0)
1633 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1634 if(!obj_name || !*obj_name)
1635 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1636 if(!attr_name || !*attr_name)
1637 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
1638 if(NULL == ainfo)
1639 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid info pointer")
1640 if(H5P_DEFAULT == lapl_id)
1641 lapl_id = H5P_LINK_ACCESS_DEFAULT;
1642 else
1643 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1644 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1645
1646 /* Open the attribute on the object header */
1647 if(NULL == (attr = H5A_open_by_name(&loc, obj_name, attr_name, lapl_id, H5AC_ind_dxpl_id)))
1648 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
1649
1650 /* Get the attribute information */
1651 if(H5A_get_info(attr, ainfo) < 0)
1652 HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
1653
1654 done:
1655 /* Cleanup on failure */
1656 if(attr && H5A_close(attr) < 0)
1657 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
1658
1659 FUNC_LEAVE_API(ret_value)
1660 } /* end H5Aget_info_by_name() */
1661
1662
1663 /*-------------------------------------------------------------------------
1664 * Function: H5Aget_info_by_idx
1665 *
1666 * Purpose: Retrieve information about an attribute, according to the
1667 * order within an index.
1668 *
1669 * Return: Success: Non-negative with information in AINFO
1670 * Failure: Negative
1671 *
1672 * Programmer: Quincey Koziol
1673 * February 8, 2007
1674 *
1675 *-------------------------------------------------------------------------
1676 */
1677 herr_t
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,H5A_info_t * ainfo,hid_t lapl_id)1678 H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
1679 H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo, hid_t lapl_id)
1680 {
1681 H5G_loc_t loc; /* Object location */
1682 H5A_t *attr = NULL; /* Attribute object for name */
1683 herr_t ret_value = SUCCEED; /* Return value */
1684
1685 FUNC_ENTER_API(FAIL)
1686 H5TRACE7("e", "i*sIiIoh*xi", loc_id, obj_name, idx_type, order, n, ainfo,
1687 lapl_id);
1688
1689 /* Check args */
1690 if(H5I_ATTR == H5I_get_type(loc_id))
1691 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1692 if(H5G_loc(loc_id, &loc) < 0)
1693 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1694 if(!obj_name || !*obj_name)
1695 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
1696 if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1697 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
1698 if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1699 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
1700 if(NULL == ainfo)
1701 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid info pointer")
1702 if(H5P_DEFAULT == lapl_id)
1703 lapl_id = H5P_LINK_ACCESS_DEFAULT;
1704 else
1705 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1706 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1707
1708 /* Open the attribute on the object header */
1709 if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id)))
1710 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
1711
1712 /* Get the attribute information */
1713 if(H5A_get_info(attr, ainfo) < 0)
1714 HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
1715
1716 done:
1717 /* Release resources */
1718 if(attr && H5A_close(attr) < 0)
1719 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
1720
1721 FUNC_LEAVE_API(ret_value)
1722 } /* end H5Aget_info_by_idx() */
1723
1724
1725 /*-------------------------------------------------------------------------
1726 * Function: H5A_get_info
1727 *
1728 * Purpose: Retrieve information about an attribute.
1729 *
1730 * Return: Success: Non-negative
1731 * Failure: Negative
1732 *
1733 * Programmer: Quincey Koziol
1734 * February 6, 2007
1735 *
1736 *-------------------------------------------------------------------------
1737 */
1738 herr_t
H5A_get_info(const H5A_t * attr,H5A_info_t * ainfo)1739 H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo)
1740 {
1741 herr_t ret_value = SUCCEED; /* Return value */
1742
1743 FUNC_ENTER_NOAPI(FAIL)
1744
1745 /* Check args */
1746 HDassert(attr);
1747 HDassert(ainfo);
1748
1749 /* Set info for attribute */
1750 ainfo->cset = attr->shared->encoding;
1751 ainfo->data_size = attr->shared->data_size;
1752 if(attr->shared->crt_idx == H5O_MAX_CRT_ORDER_IDX) {
1753 ainfo->corder_valid = FALSE;
1754 ainfo->corder = 0;
1755 } /* end if */
1756 else {
1757 ainfo->corder_valid = TRUE;
1758 ainfo->corder = attr->shared->crt_idx;
1759 } /* end else */
1760
1761 done:
1762 FUNC_LEAVE_NOAPI(ret_value)
1763 } /* end H5A_get_info() */
1764
1765
1766 /*-------------------------------------------------------------------------
1767 * Function: H5Arename
1768 *
1769 * Purpose: Rename an attribute
1770 *
1771 * Return: Success: Non-negative
1772 * Failure: Negative
1773 *
1774 * Programmer: Raymond Lu
1775 * October 23, 2002
1776 *
1777 *-------------------------------------------------------------------------
1778 */
1779 herr_t
H5Arename(hid_t loc_id,const char * old_name,const char * new_name)1780 H5Arename(hid_t loc_id, const char *old_name, const char *new_name)
1781 {
1782 H5G_loc_t loc; /* Object location */
1783 herr_t ret_value = SUCCEED; /* Return value */
1784
1785 FUNC_ENTER_API(FAIL)
1786 H5TRACE3("e", "i*s*s", loc_id, old_name, new_name);
1787
1788 /* check arguments */
1789 if(!old_name || !new_name)
1790 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "name is nil")
1791 if(H5I_ATTR == H5I_get_type(loc_id))
1792 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1793 if(H5G_loc(loc_id, & loc) < 0)
1794 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1795
1796 /* Avoid thrashing things if the names are the same */
1797 if(HDstrcmp(old_name, new_name))
1798 /* Call attribute rename routine */
1799 if(H5O_attr_rename(loc.oloc, H5AC_dxpl_id, old_name, new_name) < 0)
1800 HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
1801
1802 done:
1803 FUNC_LEAVE_API(ret_value)
1804 } /* H5Arename() */
1805
1806
1807 /*-------------------------------------------------------------------------
1808 * Function: H5Arename_by_name
1809 *
1810 * Purpose: Rename an attribute
1811 *
1812 * Return: Success: Non-negative
1813 * Failure: Negative
1814 *
1815 * Programmer: Quincey Koziol
1816 * February 20, 2007
1817 *
1818 *-------------------------------------------------------------------------
1819 */
1820 herr_t
H5Arename_by_name(hid_t loc_id,const char * obj_name,const char * old_attr_name,const char * new_attr_name,hid_t lapl_id)1821 H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name,
1822 const char *new_attr_name, hid_t lapl_id)
1823 {
1824 H5G_loc_t loc; /* Object location */
1825 H5G_loc_t obj_loc; /* Location used to open group */
1826 H5G_name_t obj_path; /* Opened object group hier. path */
1827 H5O_loc_t obj_oloc; /* Opened object object location */
1828 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
1829 herr_t ret_value = SUCCEED; /* Return value */
1830
1831 FUNC_ENTER_API(FAIL)
1832 H5TRACE5("e", "i*s*s*si", loc_id, obj_name, old_attr_name, new_attr_name,
1833 lapl_id);
1834
1835 /* check arguments */
1836 if(H5I_ATTR == H5I_get_type(loc_id))
1837 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1838 if(H5G_loc(loc_id, &loc) < 0)
1839 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1840 if(!obj_name || !*obj_name)
1841 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1842 if(!old_attr_name || !*old_attr_name)
1843 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no old attribute name")
1844 if(!new_attr_name || !*new_attr_name)
1845 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new attribute name")
1846 if(H5P_DEFAULT == lapl_id)
1847 lapl_id = H5P_LINK_ACCESS_DEFAULT;
1848 else
1849 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1850 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1851
1852 /* Avoid thrashing things if the names are the same */
1853 if(HDstrcmp(old_attr_name, new_attr_name)) {
1854 /* Set up opened group location to fill in */
1855 obj_loc.oloc = &obj_oloc;
1856 obj_loc.path = &obj_path;
1857 H5G_loc_reset(&obj_loc);
1858
1859 /* Find the object's location */
1860 if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
1861 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
1862 loc_found = TRUE;
1863
1864 /* Call attribute rename routine */
1865 if(H5O_attr_rename(obj_loc.oloc, H5AC_dxpl_id, old_attr_name, new_attr_name) < 0)
1866 HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
1867 } /* end if */
1868
1869 done:
1870 /* Release resources */
1871 if(loc_found && H5G_loc_free(&obj_loc) < 0)
1872 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
1873
1874 FUNC_LEAVE_API(ret_value)
1875 } /* H5Arename_by_name() */
1876
1877
1878 /*--------------------------------------------------------------------------
1879 NAME
1880 H5Aiterate2
1881 PURPOSE
1882 Calls a user's function for each attribute on an object
1883 USAGE
1884 herr_t H5Aiterate2(loc_id, idx_type, order, idx, op, op_data)
1885 hid_t loc_id; IN: Base location for object
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 RETURNS
1894 Returns a negative value if an error occurs, the return value of the
1895 last operator if it was non-zero (which can be a negative value), or zero
1896 if all attributes were processed.
1897
1898 DESCRIPTION
1899 This function interates over the attributes of dataset or group
1900 specified with 'loc_id' & 'obj_name'. For each attribute of the object,
1901 the 'op_data' and some additional information (specified below) are passed
1902 to the 'op' function. The iteration begins with the '*idx'
1903 object in the group and the next attribute to be processed by the operator
1904 is returned in '*idx'.
1905 The operation receives the ID for the group or dataset being iterated
1906 over ('loc_id'), the name of the current attribute about the object
1907 ('attr_name'), the attribute's "info" struct ('ainfo') and the pointer to
1908 the operator data passed in to H5Aiterate2 ('op_data'). The return values
1909 from an operator are:
1910 A. Zero causes the iterator to continue, returning zero when all
1911 attributes have been processed.
1912 B. Positive causes the iterator to immediately return that positive
1913 value, indicating short-circuit success. The iterator can be
1914 restarted at the next attribute.
1915 C. Negative causes the iterator to immediately return that value,
1916 indicating failure. The iterator can be restarted at the next
1917 attribute.
1918 --------------------------------------------------------------------------*/
1919 herr_t
H5Aiterate2(hid_t loc_id,H5_index_t idx_type,H5_iter_order_t order,hsize_t * idx,H5A_operator2_t op,void * op_data)1920 H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order,
1921 hsize_t *idx, H5A_operator2_t op, void *op_data)
1922 {
1923 H5A_attr_iter_op_t attr_op; /* Attribute operator */
1924 hsize_t start_idx; /* Index of attribute to start iterating at */
1925 hsize_t last_attr; /* Index of last attribute examined */
1926 herr_t ret_value; /* Return value */
1927
1928 FUNC_ENTER_API(FAIL)
1929 H5TRACE6("e", "iIiIo*hx*x", loc_id, idx_type, order, idx, op, op_data);
1930
1931 /* check arguments */
1932 if(H5I_ATTR == H5I_get_type(loc_id))
1933 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1934 if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1935 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
1936 if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1937 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
1938
1939 /* Build attribute operator info */
1940 attr_op.op_type = H5A_ATTR_OP_APP2;
1941 attr_op.u.app_op2 = op;
1942
1943 /* Call attribute iteration routine */
1944 last_attr = start_idx = (idx ? *idx : 0);
1945 if((ret_value = H5O_attr_iterate(loc_id, H5AC_ind_dxpl_id, idx_type, order, start_idx, &last_attr, &attr_op, op_data)) < 0)
1946 HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
1947
1948 /* Set the last attribute information */
1949 if(idx)
1950 *idx = last_attr;
1951
1952 done:
1953 FUNC_LEAVE_API(ret_value)
1954 } /* H5Aiterate2() */
1955
1956
1957 /*--------------------------------------------------------------------------
1958 NAME
1959 H5Aiterate_by_name
1960 PURPOSE
1961 Calls a user's function for each attribute on an object
1962 USAGE
1963 herr_t H5Aiterate2(loc_id, obj_name, idx_type, order, idx, op, op_data, lapl_id)
1964 hid_t loc_id; IN: Base location for object
1965 const char *obj_name; IN: Name of object relative to location
1966 H5_index_t idx_type; IN: Type of index to use
1967 H5_iter_order_t order; IN: Order to iterate over index
1968 hsize_t *idx; IN/OUT: Starting (IN) & Ending (OUT) attribute
1969 in index & order
1970 H5A_operator2_t op; IN: User's function to pass each attribute to
1971 void *op_data; IN/OUT: User's data to pass through to iterator
1972 operator function
1973 hid_t lapl_id; IN: Link access property list
1974 RETURNS
1975 Returns a negative value if an error occurs, the return value of the
1976 last operator if it was non-zero (which can be a negative value), or zero
1977 if all attributes were processed.
1978
1979 DESCRIPTION
1980 This function interates over the attributes of dataset or group
1981 specified with 'loc_id' & 'obj_name'. For each attribute of the object,
1982 the 'op_data' and some additional information (specified below) are passed
1983 to the 'op' function. The iteration begins with the '*idx'
1984 object in the group and the next attribute to be processed by the operator
1985 is returned in '*idx'.
1986 The operation receives the ID for the group or dataset being iterated
1987 over ('loc_id'), the name of the current attribute about the object
1988 ('attr_name'), the attribute's "info" struct ('ainfo') and the pointer to
1989 the operator data passed in to H5Aiterate_by_name ('op_data'). The return values
1990 from an operator are:
1991 A. Zero causes the iterator to continue, returning zero when all
1992 attributes have been processed.
1993 B. Positive causes the iterator to immediately return that positive
1994 value, indicating short-circuit success. The iterator can be
1995 restarted at the next attribute.
1996 C. Negative causes the iterator to immediately return that value,
1997 indicating failure. The iterator can be restarted at the next
1998 attribute.
1999 --------------------------------------------------------------------------*/
2000 herr_t
H5Aiterate_by_name(hid_t loc_id,const char * obj_name,H5_index_t idx_type,H5_iter_order_t order,hsize_t * idx,H5A_operator2_t op,void * op_data,hid_t lapl_id)2001 H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
2002 H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data,
2003 hid_t lapl_id)
2004 {
2005 H5G_loc_t loc; /* Object location */
2006 H5G_loc_t obj_loc; /* Location used to open group */
2007 H5G_name_t obj_path; /* Opened object group hier. path */
2008 H5O_loc_t obj_oloc; /* Opened object object location */
2009 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
2010 hid_t obj_loc_id = (-1); /* ID for object located */
2011 H5A_attr_iter_op_t attr_op; /* Attribute operator */
2012 hsize_t start_idx; /* Index of attribute to start iterating at */
2013 hsize_t last_attr; /* Index of last attribute examined */
2014 herr_t ret_value; /* Return value */
2015
2016 FUNC_ENTER_API(FAIL)
2017 H5TRACE8("e", "i*sIiIo*hx*xi", loc_id, obj_name, idx_type, order, idx, op,
2018 op_data, lapl_id);
2019
2020 /* check arguments */
2021 if(H5I_ATTR == H5I_get_type(loc_id))
2022 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
2023 if(H5G_loc(loc_id, &loc) < 0)
2024 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
2025 if(!obj_name || !*obj_name)
2026 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
2027 if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
2028 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
2029 if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
2030 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
2031 if(H5P_DEFAULT == lapl_id)
2032 lapl_id = H5P_LINK_ACCESS_DEFAULT;
2033 else
2034 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
2035 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
2036
2037 /* Set up opened group location to fill in */
2038 obj_loc.oloc = &obj_oloc;
2039 obj_loc.path = &obj_path;
2040 H5G_loc_reset(&obj_loc);
2041
2042 /* Find the object's location */
2043 if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
2044 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
2045 loc_found = TRUE;
2046
2047 /* Open the object */
2048 if((obj_loc_id = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_ind_dxpl_id, TRUE)) < 0)
2049 HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
2050
2051 /* Build attribute operator info */
2052 attr_op.op_type = H5A_ATTR_OP_APP2;
2053 attr_op.u.app_op2 = op;
2054
2055 /* Call attribute iteration routine */
2056 last_attr = start_idx = (idx ? *idx : 0);
2057 if((ret_value = H5O_attr_iterate(obj_loc_id, H5AC_ind_dxpl_id, idx_type, order, start_idx, &last_attr, &attr_op, op_data)) < 0)
2058 HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
2059
2060 /* Set the last attribute information */
2061 if(idx)
2062 *idx = last_attr;
2063
2064 done:
2065 /* Release resources */
2066 if(obj_loc_id > 0) {
2067 if(H5I_dec_app_ref(obj_loc_id) < 0)
2068 HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
2069 } /* end if */
2070 else if(loc_found && H5G_loc_free(&obj_loc) < 0)
2071 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
2072
2073 FUNC_LEAVE_API(ret_value)
2074 } /* H5Aiterate_by_name() */
2075
2076
2077 /*--------------------------------------------------------------------------
2078 NAME
2079 H5Adelete
2080 PURPOSE
2081 Deletes an attribute from a location
2082 USAGE
2083 herr_t H5Adelete(loc_id, name)
2084 hid_t loc_id; IN: Object (dataset or group) to have attribute deleted from
2085 const char *name; IN: Name of attribute to delete
2086 RETURNS
2087 Non-negative on success/Negative on failure
2088 DESCRIPTION
2089 This function removes the named attribute from a dataset or group.
2090 --------------------------------------------------------------------------*/
2091 herr_t
H5Adelete(hid_t loc_id,const char * name)2092 H5Adelete(hid_t loc_id, const char *name)
2093 {
2094 H5G_loc_t loc; /* Object location */
2095 herr_t ret_value = SUCCEED; /* Return value */
2096
2097 FUNC_ENTER_API(FAIL)
2098 H5TRACE2("e", "i*s", loc_id, name);
2099
2100 /* check arguments */
2101 if(H5I_ATTR == H5I_get_type(loc_id))
2102 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
2103 if(H5G_loc(loc_id, &loc) < 0)
2104 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
2105 if(!name || !*name)
2106 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
2107
2108 /* Delete the attribute from the location */
2109 if(H5O_attr_remove(loc.oloc, name, H5AC_dxpl_id) < 0)
2110 HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
2111
2112 done:
2113 FUNC_LEAVE_API(ret_value)
2114 } /* H5Adelete() */
2115
2116
2117 /*--------------------------------------------------------------------------
2118 NAME
2119 H5Adelete_by_name
2120 PURPOSE
2121 Deletes an attribute from a location
2122 USAGE
2123 herr_t H5Adelete_by_name(loc_id, obj_name, attr_name, lapl_id)
2124 hid_t loc_id; IN: Base location for object
2125 const char *obj_name; IN: Name of object relative to location
2126 const char *attr_name; IN: Name of attribute to delete
2127 hid_t lapl_id; IN: Link access property list
2128 RETURNS
2129 Non-negative on success/Negative on failure
2130 DESCRIPTION
2131 This function removes the named attribute from an object.
2132 --------------------------------------------------------------------------*/
2133 herr_t
H5Adelete_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,hid_t lapl_id)2134 H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
2135 hid_t lapl_id)
2136 {
2137 H5G_loc_t loc; /* Object location */
2138 H5G_loc_t obj_loc; /* Location used to open group */
2139 H5G_name_t obj_path; /* Opened object group hier. path */
2140 H5O_loc_t obj_oloc; /* Opened object object location */
2141 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
2142 herr_t ret_value = SUCCEED; /* Return value */
2143
2144 FUNC_ENTER_API(FAIL)
2145 H5TRACE4("e", "i*s*si", loc_id, obj_name, attr_name, lapl_id);
2146
2147 /* check arguments */
2148 if(H5I_ATTR == H5I_get_type(loc_id))
2149 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
2150 if(H5G_loc(loc_id, &loc) < 0)
2151 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
2152 if(!obj_name || !*obj_name)
2153 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
2154 if(!attr_name || !*attr_name)
2155 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
2156 if(H5P_DEFAULT == lapl_id)
2157 lapl_id = H5P_LINK_ACCESS_DEFAULT;
2158 else
2159 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
2160 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
2161
2162 /* Set up opened group location to fill in */
2163 obj_loc.oloc = &obj_oloc;
2164 obj_loc.path = &obj_path;
2165 H5G_loc_reset(&obj_loc);
2166
2167 /* Find the object's location */
2168 if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
2169 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
2170 loc_found = TRUE;
2171
2172 /* Delete the attribute from the location */
2173 if(H5O_attr_remove(obj_loc.oloc, attr_name, H5AC_dxpl_id) < 0)
2174 HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
2175
2176 done:
2177 /* Release resources */
2178 if(loc_found && H5G_loc_free(&obj_loc) < 0)
2179 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
2180
2181 FUNC_LEAVE_API(ret_value)
2182 } /* H5Adelete_by_name() */
2183
2184
2185 /*--------------------------------------------------------------------------
2186 NAME
2187 H5Adelete_by_idx
2188 PURPOSE
2189 Deletes an attribute from a location, according to the order within an index
2190 USAGE
2191 herr_t H5Adelete_by_idx(loc_id, obj_name, idx_type, order, n, lapl_id)
2192 hid_t loc_id; IN: Base location for object
2193 const char *obj_name; IN: Name of object relative to location
2194 H5_index_t idx_type; IN: Type of index to use
2195 H5_iter_order_t order; IN: Order to iterate over index
2196 hsize_t n; IN: Offset within index
2197 hid_t lapl_id; IN: Link access property list
2198 RETURNS
2199 Non-negative on success/Negative on failure
2200 DESCRIPTION
2201 This function removes an attribute from an object, using the IDX_TYPE
2202 index to delete the N'th attribute in ORDER direction in the index. The
2203 object is specified relative to the LOC_ID with the OBJ_NAME path. To
2204 remove an attribute on the object specified by LOC_ID, pass in "." for
2205 OBJ_NAME. The link access property list, LAPL_ID, controls aspects of
2206 the group hierarchy traversal when using the OBJ_NAME to locate the final
2207 object to operate on.
2208 --------------------------------------------------------------------------*/
2209 herr_t
H5Adelete_by_idx(hid_t loc_id,const char * obj_name,H5_index_t idx_type,H5_iter_order_t order,hsize_t n,hid_t lapl_id)2210 H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
2211 H5_iter_order_t order, hsize_t n, hid_t lapl_id)
2212 {
2213 H5G_loc_t loc; /* Object location */
2214 H5G_loc_t obj_loc; /* Location used to open group */
2215 H5G_name_t obj_path; /* Opened object group hier. path */
2216 H5O_loc_t obj_oloc; /* Opened object object location */
2217 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
2218 herr_t ret_value = SUCCEED; /* Return value */
2219
2220 FUNC_ENTER_API(FAIL)
2221 H5TRACE6("e", "i*sIiIohi", loc_id, obj_name, idx_type, order, n, lapl_id);
2222
2223 /* check arguments */
2224 if(H5I_ATTR == H5I_get_type(loc_id))
2225 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
2226 if(H5G_loc(loc_id, &loc) < 0)
2227 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
2228 if(!obj_name || !*obj_name)
2229 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
2230 if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
2231 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
2232 if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
2233 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
2234 if(H5P_DEFAULT == lapl_id)
2235 lapl_id = H5P_LINK_ACCESS_DEFAULT;
2236 else
2237 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
2238 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
2239
2240 /* Set up opened group location to fill in */
2241 obj_loc.oloc = &obj_oloc;
2242 obj_loc.path = &obj_path;
2243 H5G_loc_reset(&obj_loc);
2244
2245 /* Find the object's location */
2246 if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0)
2247 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
2248 loc_found = TRUE;
2249
2250 /* Delete the attribute from the location */
2251 if(H5O_attr_remove_by_idx(obj_loc.oloc, idx_type, order, n, H5AC_dxpl_id) < 0)
2252 HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
2253
2254 done:
2255 /* Release resources */
2256 if(loc_found && H5G_loc_free(&obj_loc) < 0)
2257 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
2258
2259 FUNC_LEAVE_API(ret_value)
2260 } /* H5Adelete_by_idx() */
2261
2262
2263 /*--------------------------------------------------------------------------
2264 NAME
2265 H5Aclose
2266 PURPOSE
2267 Close an attribute ID
2268 USAGE
2269 herr_t H5Aclose (attr_id)
2270 hid_t attr_id; IN: Attribute to release access to
2271 RETURNS
2272 Non-negative on success/Negative on failure
2273
2274 DESCRIPTION
2275 This function releases an attribute from use. Further use of the
2276 attribute ID will result in undefined behavior.
2277 --------------------------------------------------------------------------*/
2278 herr_t
H5Aclose(hid_t attr_id)2279 H5Aclose(hid_t attr_id)
2280 {
2281 herr_t ret_value = SUCCEED; /* Return value */
2282
2283 FUNC_ENTER_API(FAIL)
2284 H5TRACE1("e", "i", attr_id);
2285
2286 /* check arguments */
2287 if(NULL == H5I_object_verify(attr_id, H5I_ATTR))
2288 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
2289
2290 /* Decrement references to that atom (and close it) */
2291 if(H5I_dec_app_ref(attr_id) < 0)
2292 HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute")
2293
2294 done:
2295 FUNC_LEAVE_API(ret_value)
2296 } /* H5Aclose() */
2297
2298
2299 /*-------------------------------------------------------------------------
2300 * Function: H5A_copy
2301 *
2302 * Purpose: Copies attribute OLD_ATTR.
2303 *
2304 * Return: Success: Pointer to a new copy of the OLD_ATTR argument.
2305 *
2306 * Failure: NULL
2307 *
2308 * Programmer: Robb Matzke
2309 * Thursday, December 4, 1997
2310 *
2311 * Modification:Raymond Lu
2312 * 4 June 2008
2313 * Changed some attribute information to be shared.
2314 *
2315 *-------------------------------------------------------------------------
2316 */
2317 H5A_t *
H5A_copy(H5A_t * _new_attr,const H5A_t * old_attr)2318 H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr)
2319 {
2320 H5A_t *new_attr = NULL;
2321 hbool_t allocated_attr = FALSE; /* Whether the attribute was allocated */
2322 H5A_t *ret_value = NULL; /* Return value */
2323
2324 FUNC_ENTER_NOAPI(NULL)
2325
2326 /* check args */
2327 HDassert(old_attr);
2328
2329 /* Allocate attribute structure */
2330 if(_new_attr == NULL) {
2331 if(NULL == (new_attr = H5FL_CALLOC(H5A_t)))
2332 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
2333 allocated_attr = TRUE;
2334 } /* end if */
2335 else
2336 new_attr = _new_attr;
2337
2338 /* Copy the top level of the attribute */
2339 new_attr->sh_loc = old_attr->sh_loc;
2340
2341 /* Deep copy of the group hierarchy path */
2342 if(H5G_name_copy(&(new_attr->path), &(old_attr->path), H5_COPY_DEEP) < 0)
2343 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path")
2344
2345 /* Share some attribute information */
2346 new_attr->shared = old_attr->shared;
2347
2348 /* Increment reference count for shared object */
2349 new_attr->shared->nrefs++;
2350
2351 /* Don't open the object header for a copy */
2352 new_attr->obj_opened = FALSE;
2353
2354 /* Set the return value */
2355 ret_value = new_attr;
2356
2357 done:
2358 if(ret_value == NULL)
2359 if(allocated_attr && new_attr && H5A_close(new_attr) < 0)
2360 HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
2361
2362 FUNC_LEAVE_NOAPI(ret_value)
2363 } /* end H5A_copy() */
2364
2365
2366 /*-------------------------------------------------------------------------
2367 * Function: H5A_free
2368 *
2369 * Purpose: Frees all memory associated with an attribute, but does not
2370 * free the H5A_t structure (which should be done in H5T_close).
2371 *
2372 * Return: Non-negative on success/Negative on failure
2373 *
2374 * Programmer: Quincey Koziol
2375 * Monday, November 15, 2004
2376 *
2377 * Modifications:
2378 *
2379 *-------------------------------------------------------------------------
2380 */
2381 herr_t
H5A_free(H5A_t * attr)2382 H5A_free(H5A_t *attr)
2383 {
2384 herr_t ret_value = SUCCEED; /* Return value */
2385
2386 FUNC_ENTER_NOAPI(FAIL)
2387
2388 HDassert(attr);
2389
2390 /* Free dynamicly allocated items */
2391 if(attr->shared->name) {
2392 H5MM_xfree(attr->shared->name);
2393 attr->shared->name = NULL;
2394 }
2395 if(attr->shared->dt) {
2396 if(H5T_close(attr->shared->dt) < 0)
2397 HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info")
2398 attr->shared->dt = NULL;
2399 }
2400 if(attr->shared->ds) {
2401 if(H5S_close(attr->shared->ds) < 0)
2402 HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
2403 attr->shared->ds = NULL;
2404 }
2405 if(attr->shared->data)
2406 attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data);
2407
2408 done:
2409 FUNC_LEAVE_NOAPI(ret_value)
2410 } /* end H5A_free() */
2411
2412
2413 /*-------------------------------------------------------------------------
2414 * Function: H5A_close
2415 *
2416 * Purpose: Frees an attribute and all associated memory.
2417 *
2418 * Return: Non-negative on success/Negative on failure
2419 *
2420 * Programmer: Robb Matzke
2421 * Monday, December 8, 1997
2422 *
2423 * Modifications:
2424 * Raymond Lu
2425 * 4 June 2008
2426 * Changed some attribute object information to be shared.
2427 *-------------------------------------------------------------------------
2428 */
2429 herr_t
H5A_close(H5A_t * attr)2430 H5A_close(H5A_t *attr)
2431 {
2432 herr_t ret_value = SUCCEED; /* Return value */
2433
2434 FUNC_ENTER_NOAPI(FAIL)
2435
2436 HDassert(attr);
2437 HDassert(attr->shared);
2438
2439 /* Close the object's symbol-table entry */
2440 if(attr->obj_opened && (H5O_close(&(attr->oloc)) < 0))
2441 HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info")
2442
2443 /* Reference count can be 0. It only happens when H5A_create fails. */
2444 if(attr->shared->nrefs <= 1) {
2445 /* Free dynamicly allocated items */
2446 if(H5A_free(attr) < 0)
2447 HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
2448
2449 /* Destroy shared attribute struct */
2450 attr->shared = H5FL_FREE(H5A_shared_t, attr->shared);
2451 } /* end if */
2452 else {
2453 /* There are other references to the shared part of the attribute.
2454 * Only decrement the reference count. */
2455 --attr->shared->nrefs;
2456 } /* end else */
2457
2458 /* Free group hierarchy path */
2459 if(H5G_name_free(&(attr->path)) < 0)
2460 HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
2461
2462 attr->shared = NULL;
2463 attr = H5FL_FREE(H5A_t, attr);
2464
2465 done:
2466 FUNC_LEAVE_NOAPI(ret_value)
2467 } /* end H5A_close() */
2468
2469
2470 /*-------------------------------------------------------------------------
2471 * Function: H5A_oloc
2472 *
2473 * Purpose: Return the object location for an attribute. It's the
2474 * object location for the object to which the attribute
2475 * belongs, not the attribute itself.
2476 *
2477 * Return: Success: Ptr to entry
2478 * Failure: NULL
2479 *
2480 * Programmer: Robb Matzke
2481 * Thursday, August 6, 1998
2482 *
2483 *-------------------------------------------------------------------------
2484 */
2485 H5O_loc_t *
H5A_oloc(H5A_t * attr)2486 H5A_oloc(H5A_t *attr)
2487 {
2488 H5O_loc_t *ret_value; /* Return value */
2489
2490 FUNC_ENTER_NOAPI(NULL)
2491
2492 HDassert(attr);
2493
2494 /* Set return value */
2495 ret_value = &(attr->oloc);
2496
2497 done:
2498 FUNC_LEAVE_NOAPI(ret_value)
2499 } /* end H5A_oloc() */
2500
2501
2502 /*-------------------------------------------------------------------------
2503 * Function: H5A_nameof
2504 *
2505 * Purpose: Return the group hier. path for an attribute. It's the
2506 * group hier. path for the object to which the attribute
2507 * belongs, not the attribute itself.
2508 *
2509 * Return: Success: Ptr to entry
2510 * Failure: NULL
2511 *
2512 * Programmer: Quincey Koziol
2513 * Monday, September 12, 2005
2514 *
2515 *-------------------------------------------------------------------------
2516 */
2517 H5G_name_t *
H5A_nameof(H5A_t * attr)2518 H5A_nameof(H5A_t *attr)
2519 {
2520 H5G_name_t *ret_value; /* Return value */
2521
2522 FUNC_ENTER_NOAPI(NULL)
2523
2524 HDassert(attr);
2525
2526 /* Set return value */
2527 ret_value=&(attr->path);
2528
2529 done:
2530 FUNC_LEAVE_NOAPI(ret_value)
2531 } /* end H5A_nameof() */
2532
2533
2534 /*-------------------------------------------------------------------------
2535 * Function: H5A_type
2536 *
2537 * Purpose: Return the datatype for an attribute.
2538 *
2539 * Return: Success: Ptr to entry
2540 * Failure: NULL
2541 *
2542 * Programmer: Neil Fortner
2543 * Friday, November 11, 2011
2544 *
2545 *-------------------------------------------------------------------------
2546 */
2547 H5T_t *
H5A_type(const H5A_t * attr)2548 H5A_type(const H5A_t *attr)
2549 {
2550 H5T_t *ret_value; /* Return value */
2551
2552 FUNC_ENTER_NOAPI(NULL)
2553
2554 HDassert(attr);
2555
2556 /* Set return value */
2557 ret_value = attr->shared->dt;
2558
2559 done:
2560 FUNC_LEAVE_NOAPI(ret_value)
2561 } /* end H5A_type() */
2562
2563
2564 /*-------------------------------------------------------------------------
2565 * Function: H5Aexists
2566 *
2567 * Purpose: Checks if an attribute with a given name exists on an opened
2568 * object.
2569 *
2570 * Return: Success: TRUE/FALSE
2571 * Failure: Negative
2572 *
2573 * Programmer: Quincey Koziol
2574 * Thursday, November 1, 2007
2575 *
2576 *-------------------------------------------------------------------------
2577 */
2578 htri_t
H5Aexists(hid_t obj_id,const char * attr_name)2579 H5Aexists(hid_t obj_id, const char *attr_name)
2580 {
2581 H5G_loc_t loc; /* Object location */
2582 htri_t ret_value; /* Return value */
2583
2584 FUNC_ENTER_API(FAIL)
2585 H5TRACE2("t", "i*s", obj_id, attr_name);
2586
2587 /* check arguments */
2588 if(H5I_ATTR == H5I_get_type(obj_id))
2589 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
2590 if(H5G_loc(obj_id, &loc) < 0)
2591 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
2592 if(!attr_name || !*attr_name)
2593 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
2594
2595 /* Check if the attribute exists */
2596 if((ret_value = H5O_attr_exists(loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0)
2597 HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
2598
2599 done:
2600 FUNC_LEAVE_API(ret_value)
2601 } /* H5Aexists() */
2602
2603
2604 /*-------------------------------------------------------------------------
2605 * Function: H5Aexists_by_name
2606 *
2607 * Purpose: Checks if an attribute with a given name exists on an object.
2608 *
2609 * Return: Success: TRUE/FALSE
2610 * Failure: Negative
2611 *
2612 * Programmer: Quincey Koziol
2613 * Thursday, November 1, 2007
2614 *
2615 *-------------------------------------------------------------------------
2616 */
2617 htri_t
H5Aexists_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,hid_t lapl_id)2618 H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
2619 hid_t lapl_id)
2620 {
2621 H5G_loc_t loc; /* Object location */
2622 H5G_loc_t obj_loc; /* Location used to open group */
2623 H5G_name_t obj_path; /* Opened object group hier. path */
2624 H5O_loc_t obj_oloc; /* Opened object object location */
2625 hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
2626 htri_t ret_value; /* Return value */
2627
2628 FUNC_ENTER_API(FAIL)
2629 H5TRACE4("t", "i*s*si", loc_id, obj_name, attr_name, lapl_id);
2630
2631 /* check arguments */
2632 if(H5I_ATTR == H5I_get_type(loc_id))
2633 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
2634 if(H5G_loc(loc_id, &loc) < 0)
2635 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
2636 if(!obj_name || !*obj_name)
2637 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
2638 if(!attr_name || !*attr_name)
2639 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
2640 if(H5P_DEFAULT == lapl_id)
2641 lapl_id = H5P_LINK_ACCESS_DEFAULT;
2642 else
2643 if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
2644 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
2645
2646 /* Set up opened group location to fill in */
2647 obj_loc.oloc = &obj_oloc;
2648 obj_loc.path = &obj_path;
2649 H5G_loc_reset(&obj_loc);
2650
2651 /* Find the object's location */
2652 if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
2653 HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
2654 loc_found = TRUE;
2655
2656 /* Check if the attribute exists */
2657 if((ret_value = H5O_attr_exists(obj_loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0)
2658 HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
2659
2660 done:
2661 /* Release resources */
2662 if(loc_found && H5G_loc_free(&obj_loc) < 0)
2663 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
2664
2665 FUNC_LEAVE_API(ret_value)
2666 } /* H5Aexists_by_name() */
2667
2668