1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /****************/
15 /* Module Setup */
16 /****************/
17 
18 #define H5A_PACKAGE		/*suppress error about including H5Apkg	*/
19 #define H5O_PACKAGE		/*suppress error about including H5Opkg	*/
20 
21 /* Interface initialization */
22 #define H5_INTERFACE_INIT_FUNC	H5A_init_interface
23 
24 
25 /***********/
26 /* Headers */
27 /***********/
28 #include "H5private.h"		/* Generic Functions			*/
29 #include "H5Apkg.h"		/* Attributes				*/
30 #include "H5Eprivate.h"		/* Error handling		  	*/
31 #include "H5FLprivate.h"	/* Free Lists				*/
32 #include "H5Iprivate.h"		/* IDs			  		*/
33 #include "H5MMprivate.h"	/* Memory management			*/
34 #include "H5Opkg.h"		/* Object headers			*/
35 #include "H5Sprivate.h"		/* Dataspace functions			*/
36 #include "H5SMprivate.h"	/* Shared Object Header Messages	*/
37 
38 /****************/
39 /* Local Macros */
40 /****************/
41 
42 
43 /******************/
44 /* Local Typedefs */
45 /******************/
46 
47 /* Object header iterator callbacks */
48 /* Data structure for callback for locating the index by name */
49 typedef struct H5A_iter_cb1 {
50     const char *name;
51     int idx;
52 } H5A_iter_cb1;
53 
54 
55 /********************/
56 /* Package Typedefs */
57 /********************/
58 
59 
60 /********************/
61 /* Local Prototypes */
62 /********************/
63 
64 
65 /*********************/
66 /* Package Variables */
67 /*********************/
68 
69 
70 /*****************************/
71 /* Library Private Variables */
72 /*****************************/
73 
74 
75 /*******************/
76 /* Local Variables */
77 /*******************/
78 
79 /* Declare the free lists of H5A_t */
80 H5FL_DEFINE(H5A_t);
81 
82 /* Declare the free lists for H5A_shared_t's */
83 H5FL_DEFINE(H5A_shared_t);
84 
85 /* Declare a free list to manage blocks of type conversion data */
86 H5FL_BLK_DEFINE(attr_buf);
87 
88 /* Attribute ID class */
89 static const H5I_class_t H5I_ATTR_CLS[1] = {{
90     H5I_ATTR,                   /* ID class value */
91     H5I_CLASS_REUSE_IDS,	/* Class flags */
92     0,                          /* # of reserved IDs for class */
93     (H5I_free_t)H5A_close       /* Callback routine for closing objects of this class */
94 }};
95 
96 
97 
98 /*-------------------------------------------------------------------------
99  * Function:	H5A_init
100  *
101  * Purpose:	Initialize the interface from some other package.
102  *
103  * Return:	Success:	non-negative
104  *		Failure:	negative
105  *
106  * Programmer:	Quincey Koziol
107  *              Monday, November 27, 2006
108  *
109  *-------------------------------------------------------------------------
110  */
111 herr_t
H5A_init(void)112 H5A_init(void)
113 {
114     herr_t ret_value = SUCCEED;   /* Return value */
115 
116     FUNC_ENTER_NOAPI(FAIL)
117     /* FUNC_ENTER() does all the work */
118 
119 done:
120     FUNC_LEAVE_NOAPI(ret_value)
121 } /* end H5A_init() */
122 
123 
124 /*--------------------------------------------------------------------------
125 NAME
126    H5A_init_interface -- Initialize interface-specific information
127 USAGE
128     herr_t H5A_init_interface()
129 
130 RETURNS
131     Non-negative on success/Negative on failure
132 DESCRIPTION
133     Initializes any interface-specific data or routines.
134 
135 --------------------------------------------------------------------------*/
136 static herr_t
H5A_init_interface(void)137 H5A_init_interface(void)
138 {
139     herr_t ret_value = SUCCEED;   /* Return value */
140 
141     FUNC_ENTER_NOAPI_NOINIT
142 
143     /*
144      * Create attribute ID type.
145      */
146     if(H5I_register_type(H5I_ATTR_CLS) < 0)
147         HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to initialize interface")
148 
149 done:
150     FUNC_LEAVE_NOAPI(ret_value)
151 } /* end H5A_init_interface() */
152 
153 
154 /*--------------------------------------------------------------------------
155  NAME
156     H5A_term_interface
157  PURPOSE
158     Terminate various H5A objects
159  USAGE
160     void H5A_term_interface()
161  RETURNS
162  DESCRIPTION
163     Release any other resources allocated.
164  GLOBAL VARIABLES
165  COMMENTS, BUGS, ASSUMPTIONS
166      Can't report errors...
167  EXAMPLES
168  REVISION LOG
169 --------------------------------------------------------------------------*/
170 int
H5A_term_interface(void)171 H5A_term_interface(void)
172 {
173     int	n = 0;
174 
175     FUNC_ENTER_NOAPI_NOINIT_NOERR
176 
177     if(H5_interface_initialize_g) {
178 	if(H5I_nmembers(H5I_ATTR) > 0) {
179 	    (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE);
180             n++; /*H5I*/
181 	} /* end if */
182         else {
183             /* Close deprecated interface */
184             n += H5A__term_deprec_interface();
185 
186 	    /* Destroy the attribute object id group */
187 	    (void)H5I_dec_type_ref(H5I_ATTR);
188             n++; /*H5I*/
189 
190 	    /* Mark closed */
191 	    H5_interface_initialize_g = 0;
192 	} /* end else */
193     } /* end if */
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 H5_ATTR_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 H5_ATTR_UNUSED aapl_id)
231 {
232     H5A_t	        *attr = NULL;           /* Attribute created */
233     H5G_loc_t           loc;                    /* Object location */
234     H5T_t		*type;                  /* Datatype to use for attribute */
235     H5S_t		*space;                 /* Dataspace to use for attribute */
236     hid_t		ret_value;              /* Return value */
237 
238     FUNC_ENTER_API(FAIL)
239     H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, acpl_id, aapl_id);
240 
241     /* check arguments */
242     if(H5I_ATTR == H5I_get_type(loc_id))
243 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
244     if(H5G_loc(loc_id, &loc) < 0)
245 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
246     if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR))
247 	HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, FAIL, "no write intent on file")
248     if(!attr_name || !*attr_name)
249 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
250     if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
251 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type")
252     if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
253 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
254 
255     /* Go do the real work for attaching the attribute to the dataset */
256     if(NULL == (attr = H5A_create(&loc, attr_name, type, space, acpl_id, H5AC_dxpl_id)))
257 	HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute")
258 
259     /* Register the new attribute and get an ID for it */
260     if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
261         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
262 
263 done:
264     /* Cleanup on failure */
265     if(ret_value < 0 && attr && H5A_close(attr) < 0)
266         HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
267 
268     FUNC_LEAVE_API(ret_value)
269 } /* H5Acreate2() */
270 
271 
272 /*--------------------------------------------------------------------------
273  NAME
274     H5Acreate_by_name
275  PURPOSE
276     Creates an attribute on an object
277  USAGE
278     hid_t H5Acreate_by_name(loc_id, obj_name, attr_name, type_id, space_id, acpl_id,
279             aapl_id, lapl_id)
280         hid_t loc_id;       IN: Object (dataset or group) to be attached to
281         const char *obj_name;   IN: Name of object relative to location
282         const char *attr_name;  IN: Name of attribute to locate and open
283         hid_t type_id;          IN: ID of datatype for attribute
284         hid_t space_id;         IN: ID of dataspace for attribute
285         hid_t acpl_id;          IN: ID of creation property list (currently not used)
286         hid_t aapl_id;          IN: Attribute access property list
287         hid_t lapl_id;          IN: Link access property list
288  RETURNS
289     Non-negative on success/Negative on failure
290 
291  DESCRIPTION
292         This function creates an attribute which is attached to the object
293     specified with 'loc_id/obj_name'.  The name specified with 'attr_name' for
294     each attribute for an object must be unique for that object.  The 'type_id'
295     and 'space_id' are created with the H5T and H5S interfaces respectively.
296     The 'aapl_id' property list is currently unused, but will be used in the
297     future for optional attribute access properties.  The attribute ID returned
298     from this function must be released with H5Aclose or resource leaks will
299     develop.
300 
301 --------------------------------------------------------------------------*/
302 /* ARGSUSED */
303 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 H5_ATTR_UNUSED aapl_id,hid_t lapl_id)304 H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
305     hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t H5_ATTR_UNUSED aapl_id,
306     hid_t lapl_id)
307 {
308     H5A_t	        *attr = NULL;           /* Attribute created */
309     H5G_loc_t           loc;                    /* Object location */
310     H5G_loc_t           obj_loc;                /* Location used to open group */
311     H5G_name_t          obj_path;            	/* Opened object group hier. path */
312     H5O_loc_t           obj_oloc;            	/* Opened object object location */
313     hbool_t             loc_found = FALSE;      /* Entry at 'obj_name' found */
314     H5T_t		*type;                  /* Datatype to use for attribute */
315     H5S_t		*space;                 /* Dataspace to use for attribute */
316     hid_t		ret_value;              /* Return value */
317 
318     FUNC_ENTER_API(FAIL)
319     H5TRACE8("i", "i*s*siiiii", loc_id, obj_name, attr_name, type_id, space_id,
320              acpl_id, aapl_id, lapl_id);
321 
322     /* check arguments */
323     if(H5I_ATTR == H5I_get_type(loc_id))
324 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
325     if(H5G_loc(loc_id, &loc) < 0)
326 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
327     if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR))
328 	HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, FAIL, "no write intent on file")
329     if(!obj_name || !*obj_name)
330 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
331     if(!attr_name || !*attr_name)
332 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
333     if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
334 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type")
335     if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
336 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
337 
338     /* Set up opened group location to fill in */
339     obj_loc.oloc = &obj_oloc;
340     obj_loc.path = &obj_path;
341     H5G_loc_reset(&obj_loc);
342 
343     /* Find the object's location */
344     if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
345         HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
346     loc_found = TRUE;
347 
348     /* Go do the real work for attaching the attribute to the dataset */
349     if(NULL == (attr = H5A_create(&obj_loc, attr_name, type, space, acpl_id, H5AC_dxpl_id)))
350 	HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute")
351 
352     /* Register the new attribute and get an ID for it */
353     if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
354         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
355 done:
356     /* Release resources */
357     if(loc_found && H5G_loc_free(&obj_loc) < 0)
358         HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
359     if(ret_value < 0 && attr && H5A_close(attr) < 0)
360             HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
361 
362     FUNC_LEAVE_API(ret_value)
363 } /* H5Acreate_by_name() */
364 
365 
366 /*--------------------------------------------------------------------------
367  NAME
368     H5Aopen
369  PURPOSE
370     Opens an attribute for an object by looking up the attribute name
371  USAGE
372     hid_t H5Aopen(loc_id, attr_name, aapl_id)
373         hid_t loc_id;           IN: Object that attribute is attached to
374         const char *attr_name;  IN: Name of attribute to locate and open
375         hid_t aapl_id;          IN: Attribute access property list
376  RETURNS
377     ID of attribute on success, negative on failure
378 
379  DESCRIPTION
380         This function opens an existing attribute for access.  The attribute
381     name specified is used to look up the corresponding attribute for the
382     object.  The attribute ID returned from this function must be released with
383     H5Aclose or resource leaks will develop.
384 --------------------------------------------------------------------------*/
385 hid_t
H5Aopen(hid_t loc_id,const char * attr_name,hid_t H5_ATTR_UNUSED aapl_id)386 H5Aopen(hid_t loc_id, const char *attr_name, hid_t H5_ATTR_UNUSED aapl_id)
387 {
388     H5G_loc_t    	loc;            /* Object location */
389     H5A_t               *attr = NULL;   /* Attribute opened */
390     hid_t		ret_value;
391 
392     FUNC_ENTER_API(FAIL)
393     H5TRACE3("i", "i*si", loc_id, attr_name, aapl_id);
394 
395     /* check arguments */
396     if(H5I_ATTR == H5I_get_type(loc_id))
397 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
398     if(H5G_loc(loc_id, &loc) < 0)
399 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
400     if(!attr_name || !*attr_name)
401 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
402 
403     /* Read in attribute from object header */
404     if(NULL == (attr = H5O_attr_open_by_name(loc.oloc, attr_name, H5AC_ind_dxpl_id)))
405         HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header for attribute: '%s'", attr_name)
406 
407     /* Finish initializing attribute */
408     if(H5A_open_common(&loc, attr) < 0)
409         HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize attribute")
410 
411     /* Register the attribute and get an ID for it */
412     if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
413         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
414 
415 done:
416     /* Cleanup on failure */
417     if(ret_value < 0)
418         if(attr && H5A_close(attr) < 0)
419             HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
420 
421     FUNC_LEAVE_API(ret_value)
422 } /* H5Aopen() */
423 
424 
425 /*--------------------------------------------------------------------------
426  NAME
427     H5Aopen_by_name
428  PURPOSE
429     Opens an attribute for an object by looking up the attribute name
430  USAGE
431     hid_t H5Aopen_by_name(loc_id, obj_name, attr_name, aapl_id, lapl_id)
432         hid_t loc_id;           IN: Object that attribute is attached to
433         const char *obj_name;   IN: Name of object relative to location
434         const char *attr_name;  IN: Name of attribute to locate and open
435         hid_t aapl_id;          IN: Attribute access property list
436         hid_t lapl_id;          IN: Link access property list
437  RETURNS
438     ID of attribute on success, negative on failure
439 
440  DESCRIPTION
441         This function opens an existing attribute for access.  The attribute
442     name specified is used to look up the corresponding attribute for the
443     object.  The attribute ID returned from this function must be released with
444     H5Aclose or resource leaks will develop.
445 --------------------------------------------------------------------------*/
446 hid_t
H5Aopen_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,hid_t H5_ATTR_UNUSED aapl_id,hid_t lapl_id)447 H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
448     hid_t H5_ATTR_UNUSED aapl_id, hid_t lapl_id)
449 {
450     H5G_loc_t    	loc;            /* Object location */
451     H5A_t               *attr = NULL;   /* Attribute opened */
452     hid_t		ret_value;
453 
454     FUNC_ENTER_API(FAIL)
455     H5TRACE5("i", "i*s*sii", loc_id, obj_name, attr_name, aapl_id, lapl_id);
456 
457     /* check arguments */
458     if(H5I_ATTR == H5I_get_type(loc_id))
459 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
460     if(H5G_loc(loc_id, &loc) < 0)
461 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
462     if(!obj_name || !*obj_name)
463 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
464     if(!attr_name || !*attr_name)
465 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
466     if(H5P_DEFAULT == lapl_id)
467         lapl_id = H5P_LINK_ACCESS_DEFAULT;
468     else
469         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
470             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
471 
472     /* Open the attribute on the object header */
473     if(NULL == (attr = H5A_open_by_name(&loc, obj_name, attr_name, lapl_id, H5AC_ind_dxpl_id)))
474         HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
475 
476     /* Register the attribute and get an ID for it */
477     if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
478         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
479 
480 done:
481     /* Cleanup on failure */
482     if(ret_value < 0)
483         if(attr && H5A_close(attr) < 0)
484             HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
485 
486     FUNC_LEAVE_API(ret_value)
487 } /* H5Aopen_by_name() */
488 
489 
490 /*--------------------------------------------------------------------------
491  NAME
492     H5Aopen_by_idx
493  PURPOSE
494     Opens the n'th attribute for an object, according to the order within
495     an index
496  USAGE
497     hid_t H5Aopen_by_idx(loc_id, obj_ame, idx_type, order, n, aapl_id, lapl_id)
498         hid_t loc_id;           IN: Object that attribute is attached to
499         const char *obj_name;   IN: Name of object relative to location
500         H5_index_t idx_type;    IN: Type of index to use
501         H5_iter_order_t order;  IN: Order to iterate over index
502         hsize_t n;              IN: Index (0-based) attribute to open
503         hid_t aapl_id;          IN: Attribute access property list
504         hid_t lapl_id;          IN: Link access property list
505  RETURNS
506     ID of attribute on success, negative on failure
507 
508  DESCRIPTION
509         This function opens an existing attribute for access.  The attribute
510     index specified is used to look up the corresponding attribute for the
511     object.  The attribute ID returned from this function must be released with
512     H5Aclose or resource leaks will develop.
513 --------------------------------------------------------------------------*/
514 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 H5_ATTR_UNUSED aapl_id,hid_t lapl_id)515 H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
516     H5_iter_order_t order, hsize_t n, hid_t H5_ATTR_UNUSED aapl_id, hid_t lapl_id)
517 {
518     H5A_t       *attr = NULL;   /* Attribute opened */
519     H5G_loc_t	loc;	        /* Object location */
520     hid_t	ret_value;      /* Return value */
521 
522     FUNC_ENTER_API(FAIL)
523     H5TRACE7("i", "i*sIiIohii", loc_id, obj_name, idx_type, order, n, aapl_id,
524              lapl_id);
525 
526     /* check arguments */
527     if(H5I_ATTR == H5I_get_type(loc_id))
528 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
529     if(H5G_loc(loc_id, &loc) < 0)
530 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
531     if(!obj_name || !*obj_name)
532 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
533     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
534 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
535     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
536 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
537     if(H5P_DEFAULT == lapl_id)
538         lapl_id = H5P_LINK_ACCESS_DEFAULT;
539     else
540         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
541             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
542 
543     /* Open the attribute in the object header */
544     if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id)))
545         HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open attribute")
546 
547     /* Register the attribute and get an ID for it */
548     if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0)
549         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
550 
551 done:
552     /* Cleanup on failure */
553     if(ret_value < 0)
554         if(attr && H5A_close(attr) < 0)
555             HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
556 
557     FUNC_LEAVE_API(ret_value)
558 } /* H5Aopen_by_idx() */
559 
560 
561 /*--------------------------------------------------------------------------
562  NAME
563     H5Awrite
564  PURPOSE
565     Write out data to an attribute
566  USAGE
567     herr_t H5Awrite (attr_id, dtype_id, buf)
568         hid_t attr_id;       IN: Attribute to write
569         hid_t dtype_id;       IN: Memory datatype of buffer
570         const void *buf;     IN: Buffer of data to write
571  RETURNS
572     Non-negative on success/Negative on failure
573 
574  DESCRIPTION
575         This function writes a complete attribute to disk.
576 --------------------------------------------------------------------------*/
577 herr_t
H5Awrite(hid_t attr_id,hid_t dtype_id,const void * buf)578 H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf)
579 {
580     H5A_t *attr;                /* Attribute object for ID */
581     H5T_t *mem_type;            /* Memory datatype */
582     herr_t ret_value;           /* Return value */
583 
584     FUNC_ENTER_API(FAIL)
585     H5TRACE3("e", "ii*x", attr_id, dtype_id, buf);
586 
587     /* check arguments */
588     if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
589         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
590     if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
591         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
592     if(NULL == buf)
593         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
594 
595     /* Go write the actual data to the attribute */
596     if((ret_value = H5A_write(attr, mem_type, buf, H5AC_dxpl_id)) < 0)
597         HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
598 
599 done:
600     FUNC_LEAVE_API(ret_value)
601 } /* H5Awrite() */
602 
603 
604 /*--------------------------------------------------------------------------
605  NAME
606     H5Aread
607  PURPOSE
608     Read in data from an attribute
609  USAGE
610     herr_t H5Aread (attr_id, dtype_id, buf)
611         hid_t attr_id;       IN: Attribute to read
612         hid_t dtype_id;       IN: Memory datatype of buffer
613         void *buf;           IN: Buffer for data to read
614  RETURNS
615     Non-negative on success/Negative on failure
616 
617  DESCRIPTION
618         This function reads a complete attribute from disk.
619 --------------------------------------------------------------------------*/
620 herr_t
H5Aread(hid_t attr_id,hid_t dtype_id,void * buf)621 H5Aread(hid_t attr_id, hid_t dtype_id, void *buf)
622 {
623     H5A_t *attr;                /* Attribute object for ID */
624     H5T_t *mem_type;            /* Memory datatype */
625     herr_t ret_value;           /* Return value */
626 
627     FUNC_ENTER_API(FAIL)
628     H5TRACE3("e", "ii*x", attr_id, dtype_id, buf);
629 
630     /* check arguments */
631     if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
632         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
633     if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
634         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
635     if(NULL == buf)
636         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
637 
638     /* Go write the actual data to the attribute */
639     if((ret_value = H5A_read(attr, mem_type, buf, H5AC_ind_dxpl_id)) < 0)
640         HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute")
641 
642 done:
643     FUNC_LEAVE_API(ret_value)
644 } /* H5Aread() */
645 
646 
647 /*--------------------------------------------------------------------------
648  NAME
649     H5Aget_space
650  PURPOSE
651     Gets a copy of the dataspace for an attribute
652  USAGE
653     hid_t H5Aget_space (attr_id)
654         hid_t attr_id;       IN: Attribute to get dataspace of
655  RETURNS
656     A dataspace ID on success, negative on failure
657 
658  DESCRIPTION
659         This function retrieves a copy of the dataspace for an attribute.
660     The dataspace ID returned from this function must be released with H5Sclose
661     or resource leaks will develop.
662 --------------------------------------------------------------------------*/
663 hid_t
H5Aget_space(hid_t attr_id)664 H5Aget_space(hid_t attr_id)
665 {
666     H5A_t	*attr;                  /* Attribute object for ID */
667     H5S_t      *ds = NULL;
668     hid_t	ret_value;
669 
670     FUNC_ENTER_API(FAIL)
671     H5TRACE1("i", "i", attr_id);
672 
673     /* check arguments */
674     if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
675         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
676 
677     if(NULL == (ds = H5A_get_space(attr)))
678         HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of attribute")
679 
680     /* Atomize */
681     if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0)
682         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
683 
684 done:
685     if(ret_value < 0) {
686         if(ds && (H5S_close(ds) < 0))
687             HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
688     } /* end if */
689 
690     FUNC_LEAVE_API(ret_value)
691 } /* H5Aget_space() */
692 
693 
694 /*--------------------------------------------------------------------------
695  NAME
696     H5Aget_type
697  PURPOSE
698     Gets a copy of the datatype for an attribute
699  USAGE
700     hid_t H5Aget_type (attr_id)
701         hid_t attr_id;       IN: Attribute to get datatype of
702  RETURNS
703     A datatype ID on success, negative on failure
704 
705  DESCRIPTION
706         This function retrieves a copy of the datatype for an attribute.
707     The datatype ID returned from this function must be released with H5Tclose
708     or resource leaks will develop.
709 --------------------------------------------------------------------------*/
710 hid_t
H5Aget_type(hid_t attr_id)711 H5Aget_type(hid_t attr_id)
712 {
713     H5A_t	*attr;          /* Attribute object for ID */
714     H5T_t      *dt = NULL;
715     hid_t	 ret_value;     /* Return value */
716 
717     FUNC_ENTER_API(FAIL)
718     H5TRACE1("i", "i", attr_id);
719 
720     /* check arguments */
721     if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
722         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
723 
724     if(NULL == (dt = H5A_get_type(attr)))
725         HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of attribute")
726 
727     /* Create an atom */
728     if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
729         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype")
730 
731 done:
732     if(ret_value < 0) {
733         if(dt && (H5T_close(dt) < 0))
734             HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype")
735     } /* end if */
736 
737     FUNC_LEAVE_API(ret_value)
738 } /* H5Aget_type() */
739 
740 
741 /*--------------------------------------------------------------------------
742  NAME
743     H5Aget_create_plist
744  PURPOSE
745     Gets a copy of the creation property list for an attribute
746  USAGE
747     hssize_t H5Aget_create_plist (attr_id, buf_size, buf)
748         hid_t attr_id;      IN: Attribute to get name of
749  RETURNS
750     This function returns the ID of a copy of the attribute's creation
751     property list, or negative on failure.
752 
753  ERRORS
754 
755  DESCRIPTION
756         This function returns a copy of the creation property list for
757     an attribute.  The resulting ID must be closed with H5Pclose() or
758     resource leaks will occur.
759 --------------------------------------------------------------------------*/
760 hid_t
H5Aget_create_plist(hid_t attr_id)761 H5Aget_create_plist(hid_t attr_id)
762 {
763     H5A_t		*attr;               /* Attribute object for ID */
764     hid_t		ret_value;
765 
766     FUNC_ENTER_API(FAIL)
767     H5TRACE1("i", "i", attr_id);
768 
769     HDassert(H5P_LST_ATTRIBUTE_CREATE_ID_g != -1);
770 
771     /* Get attribute and default attribute creation property list*/
772     if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
773 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
774 
775     if((ret_value = H5A_get_create_plist(attr)) < 0)
776         HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for attr")
777 
778 done:
779     FUNC_LEAVE_API(ret_value)
780 } /* end H5Aget_create_plist() */
781 
782 
783 /*--------------------------------------------------------------------------
784  NAME
785     H5Aget_name
786  PURPOSE
787     Gets a copy of the name for an attribute
788  USAGE
789     hssize_t H5Aget_name (attr_id, buf_size, buf)
790         hid_t attr_id;      IN: Attribute to get name of
791         size_t buf_size;    IN: The size of the buffer to store the string in.
792         char *buf;          IN: Buffer to store name in
793  RETURNS
794     This function returns the length of the attribute's name (which may be
795     longer than 'buf_size') on success or negative for failure.
796 
797  DESCRIPTION
798         This function retrieves the name of an attribute for an attribute ID.
799     Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string
800     terminator.  If the name of the attribute is longer than 'buf_size'-1,
801     the string terminator is stored in the last position of the buffer to
802     properly terminate the string.
803 --------------------------------------------------------------------------*/
804 ssize_t
H5Aget_name(hid_t attr_id,size_t buf_size,char * buf)805 H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
806 {
807     H5A_t		*my_attr;               /* Attribute object for ID */
808     ssize_t		ret_value;
809 
810     FUNC_ENTER_API(FAIL)
811     H5TRACE3("Zs", "iz*s", attr_id, buf_size, buf);
812 
813     /* check arguments */
814     if(NULL == (my_attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
815         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
816     if(!buf && buf_size)
817 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
818 
819     /* Call private function in turn */
820     if(0 > (ret_value = H5A_get_name(my_attr, buf_size, buf)))
821 	HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name")
822 
823 done:
824     FUNC_LEAVE_API(ret_value)
825 } /* H5Aget_name() */
826 
827 
828 /*-------------------------------------------------------------------------
829  * Function:	H5Aget_name_by_idx
830  *
831  * Purpose:	Retrieve name of an attribute, according to the
832  *		order within an index.
833  *
834  *              Same pattern of behavior as H5Iget_name.
835  *
836  * Return:	Success:	Non-negative length of name, with information
837  *				in NAME buffer
838  *		Failure:	Negative
839  *
840  * Programmer:	Quincey Koziol
841  *              February  8, 2007
842  *
843  *-------------------------------------------------------------------------
844  */
845 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)846 H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
847     H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size,
848     hid_t lapl_id)
849 {
850     H5G_loc_t   loc;            /* Object location */
851     H5A_t	*attr = NULL;   /* Attribute object for name */
852     ssize_t	ret_value;      /* Return value */
853 
854     FUNC_ENTER_API(FAIL)
855     H5TRACE8("Zs", "i*sIiIohxzi", loc_id, obj_name, idx_type, order, n, name, size,
856              lapl_id);
857 
858     /* Check args */
859     if(H5I_ATTR == H5I_get_type(loc_id))
860 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
861     if(H5G_loc(loc_id, &loc) < 0)
862 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
863     if(!obj_name || !*obj_name)
864 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
865     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
866 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
867     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
868 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
869     if(H5P_DEFAULT == lapl_id)
870         lapl_id = H5P_LINK_ACCESS_DEFAULT;
871     else
872         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
873             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
874 
875     /* Open the attribute on the object header */
876     if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id)))
877         HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
878 
879     /* Get the length of the name */
880     ret_value = (ssize_t)HDstrlen(attr->shared->name);
881 
882     /* Copy the name into the user's buffer, if given */
883     if(name) {
884         HDstrncpy(name, attr->shared->name, MIN((size_t)(ret_value + 1), size));
885         if((size_t)ret_value >= size)
886             name[size - 1]='\0';
887     } /* end if */
888 
889 done:
890     /* Release resources */
891     if(attr && H5A_close(attr) < 0)
892         HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
893 
894     FUNC_LEAVE_API(ret_value)
895 } /* end H5Aget_name_by_idx() */
896 
897 
898 /*-------------------------------------------------------------------------
899  * Function:	H5Aget_storage_size
900  *
901  * Purpose:	Returns the amount of storage size that is required for this
902  *		attribute.
903  *
904  * Return:	Success:	The amount of storage size allocated for the
905  *				attribute.  The return value may be zero
906  *                              if no data has been stored.
907  *
908  *		Failure:	Zero
909  *
910  * Programmer:	Raymond Lu
911  *              October 23, 2002
912  *
913  *-------------------------------------------------------------------------
914  */
915 hsize_t
H5Aget_storage_size(hid_t attr_id)916 H5Aget_storage_size(hid_t attr_id)
917 {
918     H5A_t	*attr;               /* Attribute object for ID */
919     hsize_t	ret_value;      /* Return value */
920 
921     FUNC_ENTER_API(0)
922     H5TRACE1("h", "i", attr_id);
923 
924     /* Check args */
925     if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
926         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute")
927 
928     /* Set return value */
929     ret_value = attr->shared->data_size;
930 
931 done:
932     FUNC_LEAVE_API(ret_value)
933 } /* end H5Aget_storage_size() */
934 
935 
936 /*-------------------------------------------------------------------------
937  * Function:	H5Aget_info
938  *
939  * Purpose:	Retrieve information about an attribute.
940  *
941  * Return:	Success:	Non-negative
942  *		Failure:	Negative
943  *
944  * Programmer:	Quincey Koziol
945  *              February  6, 2007
946  *
947  *-------------------------------------------------------------------------
948  */
949 herr_t
H5Aget_info(hid_t attr_id,H5A_info_t * ainfo)950 H5Aget_info(hid_t attr_id, H5A_info_t *ainfo)
951 {
952     H5A_t	*attr;                  /* Attribute object for name */
953     herr_t	ret_value = SUCCEED;    /* Return value */
954 
955     FUNC_ENTER_API(FAIL)
956     H5TRACE2("e", "i*x", attr_id, ainfo);
957 
958     /* Check args */
959     if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
960         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
961 
962     /* Get the attribute information */
963     if(H5A_get_info(attr, ainfo) < 0)
964 	HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
965 
966 done:
967     FUNC_LEAVE_API(ret_value)
968 } /* end H5Aget_info() */
969 
970 
971 /*-------------------------------------------------------------------------
972  * Function:	H5Aget_info_by_name
973  *
974  * Purpose:	Retrieve information about an attribute by name.
975  *
976  * Return:	Success:	Non-negative
977  *		Failure:	Negative
978  *
979  * Programmer:	Quincey Koziol
980  *              February  6, 2007
981  *
982  *-------------------------------------------------------------------------
983  */
984 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)985 H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
986     H5A_info_t *ainfo, hid_t lapl_id)
987 {
988     H5G_loc_t   loc;                    /* Object location */
989     H5A_t	*attr = NULL;           /* Attribute object for name */
990     herr_t	ret_value = SUCCEED;    /* Return value */
991 
992     FUNC_ENTER_API(FAIL)
993     H5TRACE5("e", "i*s*s*xi", loc_id, obj_name, attr_name, ainfo, lapl_id);
994 
995     /* Check args */
996     if(H5I_ATTR == H5I_get_type(loc_id))
997 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
998     if(H5G_loc(loc_id, &loc) < 0)
999 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1000     if(!obj_name || !*obj_name)
1001 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1002     if(!attr_name || !*attr_name)
1003 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
1004     if(NULL == ainfo)
1005         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid info pointer")
1006     if(H5P_DEFAULT == lapl_id)
1007         lapl_id = H5P_LINK_ACCESS_DEFAULT;
1008     else
1009         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1010             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1011 
1012     /* Open the attribute on the object header */
1013     if(NULL == (attr = H5A_open_by_name(&loc, obj_name, attr_name, lapl_id, H5AC_ind_dxpl_id)))
1014         HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
1015 
1016     /* Get the attribute information */
1017     if(H5A_get_info(attr, ainfo) < 0)
1018 	HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
1019 
1020 done:
1021     /* Cleanup on failure */
1022     if(attr && H5A_close(attr) < 0)
1023         HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
1024 
1025     FUNC_LEAVE_API(ret_value)
1026 } /* end H5Aget_info_by_name() */
1027 
1028 
1029 /*-------------------------------------------------------------------------
1030  * Function:	H5Aget_info_by_idx
1031  *
1032  * Purpose:	Retrieve information about an attribute, according to the
1033  *		order within an index.
1034  *
1035  * Return:	Success:	Non-negative with information in AINFO
1036  *		Failure:	Negative
1037  *
1038  * Programmer:	Quincey Koziol
1039  *              February  8, 2007
1040  *
1041  *-------------------------------------------------------------------------
1042  */
1043 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)1044 H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
1045     H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo, hid_t lapl_id)
1046 {
1047     H5G_loc_t   loc;                    /* Object location */
1048     H5A_t	*attr = NULL;           /* Attribute object for name */
1049     herr_t	ret_value = SUCCEED;    /* Return value */
1050 
1051     FUNC_ENTER_API(FAIL)
1052     H5TRACE7("e", "i*sIiIoh*xi", loc_id, obj_name, idx_type, order, n, ainfo,
1053              lapl_id);
1054 
1055     /* Check args */
1056     if(H5I_ATTR == H5I_get_type(loc_id))
1057 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1058     if(H5G_loc(loc_id, &loc) < 0)
1059 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1060     if(!obj_name || !*obj_name)
1061 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
1062     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1063 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
1064     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1065 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
1066     if(NULL == ainfo)
1067         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid info pointer")
1068     if(H5P_DEFAULT == lapl_id)
1069         lapl_id = H5P_LINK_ACCESS_DEFAULT;
1070     else
1071         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1072             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1073 
1074     /* Open the attribute on the object header */
1075     if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id)))
1076         HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
1077 
1078     /* Get the attribute information */
1079     if(H5A_get_info(attr, ainfo) < 0)
1080 	HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
1081 
1082 done:
1083     /* Release resources */
1084     if(attr && H5A_close(attr) < 0)
1085         HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
1086 
1087     FUNC_LEAVE_API(ret_value)
1088 } /* end H5Aget_info_by_idx() */
1089 
1090 
1091 /*-------------------------------------------------------------------------
1092  * Function:	H5Arename
1093  *
1094  * Purpose:     Rename an attribute
1095  *
1096  * Return:	Success:             Non-negative
1097  *		Failure:             Negative
1098  *
1099  * Programmer:	Raymond Lu
1100  *              October 23, 2002
1101  *
1102  *-------------------------------------------------------------------------
1103  */
1104 herr_t
H5Arename(hid_t loc_id,const char * old_name,const char * new_name)1105 H5Arename(hid_t loc_id, const char *old_name, const char *new_name)
1106 {
1107     herr_t	ret_value = SUCCEED;    /* Return value */
1108 
1109     FUNC_ENTER_API(FAIL)
1110     H5TRACE3("e", "i*s*s", loc_id, old_name, new_name);
1111 
1112     /* check arguments */
1113     if(!old_name || !new_name)
1114 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "name is nil")
1115     if(H5I_ATTR == H5I_get_type(loc_id))
1116 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1117 
1118     /* Avoid thrashing things if the names are the same */
1119     if(HDstrcmp(old_name, new_name)) {
1120         H5G_loc_t	loc;	                /* Object location */
1121 
1122         if(H5G_loc(loc_id, & loc) < 0)
1123             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1124 
1125         /* Call private attribute rename routine */
1126         if(H5O_attr_rename(loc.oloc, H5AC_dxpl_id, old_name, new_name) < 0)
1127             HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
1128     } /* end if */
1129 
1130 done:
1131     FUNC_LEAVE_API(ret_value)
1132 } /* H5Arename() */
1133 
1134 
1135 /*-------------------------------------------------------------------------
1136  * Function:	H5Arename_by_name
1137  *
1138  * Purpose:     Rename an attribute
1139  *
1140  * Return:	Success:             Non-negative
1141  *		Failure:             Negative
1142  *
1143  * Programmer:	Quincey Koziol
1144  *              February 20, 2007
1145  *
1146  *-------------------------------------------------------------------------
1147  */
1148 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)1149 H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name,
1150     const char *new_attr_name, hid_t lapl_id)
1151 {
1152     herr_t	ret_value = SUCCEED;    /* Return value */
1153 
1154     FUNC_ENTER_API(FAIL)
1155     H5TRACE5("e", "i*s*s*si", loc_id, obj_name, old_attr_name, new_attr_name,
1156              lapl_id);
1157 
1158     /* check arguments */
1159     if(H5I_ATTR == H5I_get_type(loc_id))
1160 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1161     if(!obj_name || !*obj_name)
1162 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1163     if(!old_attr_name || !*old_attr_name)
1164 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no old attribute name")
1165     if(!new_attr_name || !*new_attr_name)
1166 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new attribute name")
1167     if(H5P_DEFAULT == lapl_id)
1168         lapl_id = H5P_LINK_ACCESS_DEFAULT;
1169     else
1170         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1171             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1172 
1173     /* Avoid thrashing things if the names are the same */
1174     if(HDstrcmp(old_attr_name, new_attr_name)) {
1175         H5G_loc_t loc;                /* Object location */
1176 
1177         if(H5G_loc(loc_id, & loc) < 0)
1178             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1179 
1180         /* Call private attribute rename routine */
1181         if(H5A_rename_by_name(loc, obj_name, old_attr_name, new_attr_name, lapl_id, H5AC_dxpl_id) < 0)
1182             HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
1183     } /* end if */
1184 
1185 done:
1186     FUNC_LEAVE_API(ret_value)
1187 } /* H5Arename_by_name() */
1188 
1189 
1190 /*--------------------------------------------------------------------------
1191  NAME
1192     H5Aiterate2
1193  PURPOSE
1194     Calls a user's function for each attribute on an object
1195  USAGE
1196     herr_t H5Aiterate2(loc_id, idx_type, order, idx, op, op_data)
1197         hid_t loc_id;           IN: Base location for object
1198         H5_index_t idx_type;    IN: Type of index to use
1199         H5_iter_order_t order;  IN: Order to iterate over index
1200         hsize_t *idx;           IN/OUT: Starting (IN) & Ending (OUT) attribute
1201                                     in index & order
1202         H5A_operator2_t op;     IN: User's function to pass each attribute to
1203         void *op_data;          IN/OUT: User's data to pass through to iterator
1204                                     operator function
1205  RETURNS
1206         Returns a negative value if an error occurs, the return value of the
1207     last operator if it was non-zero (which can be a negative value), or zero
1208     if all attributes were processed.
1209 
1210  DESCRIPTION
1211         This function interates over the attributes of dataset or group
1212     specified with 'loc_id' & 'obj_name'.  For each attribute of the object,
1213     the 'op_data' and some additional information (specified below) are passed
1214     to the 'op' function.  The iteration begins with the '*idx'
1215     object in the group and the next attribute to be processed by the operator
1216     is returned in '*idx'.
1217         The operation receives the ID for the group or dataset being iterated
1218     over ('loc_id'), the name of the current attribute about the object
1219     ('attr_name'), the attribute's "info" struct ('ainfo') and the pointer to
1220     the operator data passed in to H5Aiterate2 ('op_data').  The return values
1221     from an operator are:
1222         A. Zero causes the iterator to continue, returning zero when all
1223             attributes have been processed.
1224         B. Positive causes the iterator to immediately return that positive
1225             value, indicating short-circuit success.  The iterator can be
1226             restarted at the next attribute.
1227         C. Negative causes the iterator to immediately return that value,
1228             indicating failure.  The iterator can be restarted at the next
1229             attribute.
1230 --------------------------------------------------------------------------*/
1231 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)1232 H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order,
1233     hsize_t *idx, H5A_operator2_t op, void *op_data)
1234 {
1235     H5A_attr_iter_op_t attr_op; /* Attribute operator */
1236     hsize_t	start_idx;      /* Index of attribute to start iterating at */
1237     hsize_t	last_attr;      /* Index of last attribute examined */
1238     herr_t	ret_value;      /* Return value */
1239 
1240     FUNC_ENTER_API(FAIL)
1241     H5TRACE6("e", "iIiIo*hx*x", loc_id, idx_type, order, idx, op, op_data);
1242 
1243     /* check arguments */
1244     if(H5I_ATTR == H5I_get_type(loc_id))
1245 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1246     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1247 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
1248     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1249 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
1250 
1251     /* Build attribute operator info */
1252     attr_op.op_type = H5A_ATTR_OP_APP2;
1253     attr_op.u.app_op2 = op;
1254 
1255     /* Call attribute iteration routine */
1256     last_attr = start_idx = (idx ? *idx : 0);
1257     if((ret_value = H5O_attr_iterate(loc_id, H5AC_ind_dxpl_id, idx_type, order, start_idx, &last_attr, &attr_op, op_data)) < 0)
1258         HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
1259 
1260     /* Set the last attribute information */
1261     if(idx)
1262         *idx = last_attr;
1263 
1264 done:
1265     FUNC_LEAVE_API(ret_value)
1266 } /* H5Aiterate2() */
1267 
1268 
1269 /*--------------------------------------------------------------------------
1270  NAME
1271     H5Aiterate_by_name
1272  PURPOSE
1273     Calls a user's function for each attribute on an object
1274  USAGE
1275     herr_t H5Aiterate2(loc_id, obj_name, idx_type, order, idx, op, op_data, lapl_id)
1276         hid_t loc_id;           IN: Base location for object
1277         const char *obj_name;   IN: Name of object relative to location
1278         H5_index_t idx_type;    IN: Type of index to use
1279         H5_iter_order_t order;  IN: Order to iterate over index
1280         hsize_t *idx;           IN/OUT: Starting (IN) & Ending (OUT) attribute
1281                                     in index & order
1282         H5A_operator2_t op;     IN: User's function to pass each attribute to
1283         void *op_data;          IN/OUT: User's data to pass through to iterator
1284                                     operator function
1285         hid_t lapl_id;          IN: Link access property list
1286  RETURNS
1287         Returns a negative value if an error occurs, the return value of the
1288     last operator if it was non-zero (which can be a negative value), or zero
1289     if all attributes were processed.
1290 
1291  DESCRIPTION
1292         This function interates over the attributes of dataset or group
1293     specified with 'loc_id' & 'obj_name'.  For each attribute of the object,
1294     the 'op_data' and some additional information (specified below) are passed
1295     to the 'op' function.  The iteration begins with the '*idx'
1296     object in the group and the next attribute to be processed by the operator
1297     is returned in '*idx'.
1298         The operation receives the ID for the group or dataset being iterated
1299     over ('loc_id'), the name of the current attribute about the object
1300     ('attr_name'), the attribute's "info" struct ('ainfo') and the pointer to
1301     the operator data passed in to H5Aiterate_by_name ('op_data').  The return values
1302     from an operator are:
1303         A. Zero causes the iterator to continue, returning zero when all
1304             attributes have been processed.
1305         B. Positive causes the iterator to immediately return that positive
1306             value, indicating short-circuit success.  The iterator can be
1307             restarted at the next attribute.
1308         C. Negative causes the iterator to immediately return that value,
1309             indicating failure.  The iterator can be restarted at the next
1310             attribute.
1311 --------------------------------------------------------------------------*/
1312 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)1313 H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
1314     H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data,
1315     hid_t lapl_id)
1316 {
1317     H5G_loc_t	loc;	        /* Object location */
1318     H5G_loc_t   obj_loc;        /* Location used to open group */
1319     H5G_name_t  obj_path;       /* Opened object group hier. path */
1320     H5O_loc_t   obj_oloc;       /* Opened object object location */
1321     hbool_t     loc_found = FALSE;      /* Entry at 'obj_name' found */
1322     hid_t       obj_loc_id = (-1);      /* ID for object located */
1323     H5A_attr_iter_op_t attr_op; /* Attribute operator */
1324     hsize_t	start_idx;      /* Index of attribute to start iterating at */
1325     hsize_t	last_attr;      /* Index of last attribute examined */
1326     herr_t	ret_value;      /* Return value */
1327 
1328     FUNC_ENTER_API(FAIL)
1329     H5TRACE8("e", "i*sIiIo*hx*xi", loc_id, obj_name, idx_type, order, idx, op,
1330              op_data, lapl_id);
1331 
1332     /* check arguments */
1333     if(H5I_ATTR == H5I_get_type(loc_id))
1334 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1335     if(H5G_loc(loc_id, &loc) < 0)
1336 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1337     if(!obj_name || !*obj_name)
1338 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1339     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1340 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
1341     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1342 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
1343     if(H5P_DEFAULT == lapl_id)
1344         lapl_id = H5P_LINK_ACCESS_DEFAULT;
1345     else
1346         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1347             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1348 
1349     /* Set up opened group location to fill in */
1350     obj_loc.oloc = &obj_oloc;
1351     obj_loc.path = &obj_path;
1352     H5G_loc_reset(&obj_loc);
1353 
1354     /* Find the object's location */
1355     if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
1356         HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
1357     loc_found = TRUE;
1358 
1359     /* Open the object */
1360     if((obj_loc_id = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_ind_dxpl_id, TRUE)) < 0)
1361         HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open object")
1362 
1363     /* Build attribute operator info */
1364     attr_op.op_type = H5A_ATTR_OP_APP2;
1365     attr_op.u.app_op2 = op;
1366 
1367     /* Call attribute iteration routine */
1368     last_attr = start_idx = (idx ? *idx : 0);
1369     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)
1370         HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes");
1371 
1372     /* Set the last attribute information */
1373     if(idx)
1374         *idx = last_attr;
1375 
1376 done:
1377     /* Release resources */
1378     if(obj_loc_id > 0) {
1379         if(H5I_dec_app_ref(obj_loc_id) < 0)
1380             HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
1381     } /* end if */
1382     else if(loc_found && H5G_loc_free(&obj_loc) < 0)
1383         HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
1384 
1385     FUNC_LEAVE_API(ret_value)
1386 } /* H5Aiterate_by_name() */
1387 
1388 
1389 /*--------------------------------------------------------------------------
1390  NAME
1391     H5Adelete
1392  PURPOSE
1393     Deletes an attribute from a location
1394  USAGE
1395     herr_t H5Adelete(loc_id, name)
1396         hid_t loc_id;       IN: Object (dataset or group) to have attribute deleted from
1397         const char *name;   IN: Name of attribute to delete
1398  RETURNS
1399     Non-negative on success/Negative on failure
1400  DESCRIPTION
1401     This function removes the named attribute from a dataset or group.
1402 --------------------------------------------------------------------------*/
1403 herr_t
H5Adelete(hid_t loc_id,const char * name)1404 H5Adelete(hid_t loc_id, const char *name)
1405 {
1406     H5G_loc_t	loc;		        /* Object location */
1407     herr_t	ret_value = SUCCEED;    /* Return value */
1408 
1409     FUNC_ENTER_API(FAIL)
1410     H5TRACE2("e", "i*s", loc_id, name);
1411 
1412     /* check arguments */
1413     if(H5I_ATTR == H5I_get_type(loc_id))
1414 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1415     if(H5G_loc(loc_id, &loc) < 0)
1416 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1417     if(!name || !*name)
1418 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
1419 
1420     /* Delete the attribute from the location */
1421     if(H5O_attr_remove(loc.oloc, name, H5AC_dxpl_id) < 0)
1422         HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
1423 
1424 done:
1425     FUNC_LEAVE_API(ret_value)
1426 } /* H5Adelete() */
1427 
1428 
1429 /*--------------------------------------------------------------------------
1430  NAME
1431     H5Adelete_by_name
1432  PURPOSE
1433     Deletes an attribute from a location
1434  USAGE
1435     herr_t H5Adelete_by_name(loc_id, obj_name, attr_name, lapl_id)
1436         hid_t loc_id;           IN: Base location for object
1437         const char *obj_name;   IN: Name of object relative to location
1438         const char *attr_name;  IN: Name of attribute to delete
1439         hid_t lapl_id;          IN: Link access property list
1440  RETURNS
1441     Non-negative on success/Negative on failure
1442  DESCRIPTION
1443     This function removes the named attribute from an object.
1444 --------------------------------------------------------------------------*/
1445 herr_t
H5Adelete_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,hid_t lapl_id)1446 H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
1447     hid_t lapl_id)
1448 {
1449     H5G_loc_t	loc;		        /* Object location */
1450     H5G_loc_t   obj_loc;                /* Location used to open group */
1451     H5G_name_t  obj_path;            	/* Opened object group hier. path */
1452     H5O_loc_t   obj_oloc;            	/* Opened object object location */
1453     hbool_t     loc_found = FALSE;      /* Entry at 'obj_name' found */
1454     herr_t	ret_value = SUCCEED;    /* Return value */
1455 
1456     FUNC_ENTER_API(FAIL)
1457     H5TRACE4("e", "i*s*si", loc_id, obj_name, attr_name, lapl_id);
1458 
1459     /* check arguments */
1460     if(H5I_ATTR == H5I_get_type(loc_id))
1461 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1462     if(H5G_loc(loc_id, &loc) < 0)
1463 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1464     if(!obj_name || !*obj_name)
1465 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1466     if(!attr_name || !*attr_name)
1467 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
1468     if(H5P_DEFAULT == lapl_id)
1469         lapl_id = H5P_LINK_ACCESS_DEFAULT;
1470     else
1471         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1472             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1473 
1474     /* Set up opened group location to fill in */
1475     obj_loc.oloc = &obj_oloc;
1476     obj_loc.path = &obj_path;
1477     H5G_loc_reset(&obj_loc);
1478 
1479     /* Find the object's location */
1480     if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
1481         HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
1482     loc_found = TRUE;
1483 
1484     /* Delete the attribute from the location */
1485     if(H5O_attr_remove(obj_loc.oloc, attr_name, H5AC_dxpl_id) < 0)
1486         HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
1487 
1488 done:
1489     /* Release resources */
1490     if(loc_found && H5G_loc_free(&obj_loc) < 0)
1491         HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
1492 
1493     FUNC_LEAVE_API(ret_value)
1494 } /* H5Adelete_by_name() */
1495 
1496 
1497 /*--------------------------------------------------------------------------
1498  NAME
1499     H5Adelete_by_idx
1500  PURPOSE
1501     Deletes an attribute from a location, according to the order within an index
1502  USAGE
1503     herr_t H5Adelete_by_idx(loc_id, obj_name, idx_type, order, n, lapl_id)
1504         hid_t loc_id;           IN: Base location for object
1505         const char *obj_name;   IN: Name of object relative to location
1506         H5_index_t idx_type;    IN: Type of index to use
1507         H5_iter_order_t order;  IN: Order to iterate over index
1508         hsize_t n;              IN: Offset within index
1509         hid_t lapl_id;          IN: Link access property list
1510  RETURNS
1511     Non-negative on success/Negative on failure
1512  DESCRIPTION
1513         This function removes an attribute from an object, using the IDX_TYPE
1514     index to delete the N'th attribute in ORDER direction in the index.  The
1515     object is specified relative to the LOC_ID with the OBJ_NAME path.  To
1516     remove an attribute on the object specified by LOC_ID, pass in "." for
1517     OBJ_NAME.  The link access property list, LAPL_ID, controls aspects of
1518     the group hierarchy traversal when using the OBJ_NAME to locate the final
1519     object to operate on.
1520 --------------------------------------------------------------------------*/
1521 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)1522 H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
1523     H5_iter_order_t order, hsize_t n, hid_t lapl_id)
1524 {
1525     H5G_loc_t	loc;		        /* Object location */
1526     H5G_loc_t   obj_loc;                /* Location used to open group */
1527     H5G_name_t  obj_path;            	/* Opened object group hier. path */
1528     H5O_loc_t   obj_oloc;            	/* Opened object object location */
1529     hbool_t     loc_found = FALSE;      /* Entry at 'obj_name' found */
1530     herr_t	ret_value = SUCCEED;    /* Return value */
1531 
1532     FUNC_ENTER_API(FAIL)
1533     H5TRACE6("e", "i*sIiIohi", loc_id, obj_name, idx_type, order, n, lapl_id);
1534 
1535     /* check arguments */
1536     if(H5I_ATTR == H5I_get_type(loc_id))
1537 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1538     if(H5G_loc(loc_id, &loc) < 0)
1539 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1540     if(!obj_name || !*obj_name)
1541 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1542     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
1543 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
1544     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
1545 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
1546     if(H5P_DEFAULT == lapl_id)
1547         lapl_id = H5P_LINK_ACCESS_DEFAULT;
1548     else
1549         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1550             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1551 
1552     /* Set up opened group location to fill in */
1553     obj_loc.oloc = &obj_oloc;
1554     obj_loc.path = &obj_path;
1555     H5G_loc_reset(&obj_loc);
1556 
1557     /* Find the object's location */
1558     if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
1559         HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
1560     loc_found = TRUE;
1561 
1562     /* Delete the attribute from the location */
1563     if(H5O_attr_remove_by_idx(obj_loc.oloc, idx_type, order, n, H5AC_dxpl_id) < 0)
1564         HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
1565 
1566 done:
1567     /* Release resources */
1568     if(loc_found && H5G_loc_free(&obj_loc) < 0)
1569         HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location")
1570 
1571     FUNC_LEAVE_API(ret_value)
1572 } /* H5Adelete_by_idx() */
1573 
1574 
1575 /*--------------------------------------------------------------------------
1576  NAME
1577     H5Aclose
1578  PURPOSE
1579     Close an attribute ID
1580  USAGE
1581     herr_t H5Aclose (attr_id)
1582         hid_t attr_id;       IN: Attribute to release access to
1583  RETURNS
1584     Non-negative on success/Negative on failure
1585 
1586  DESCRIPTION
1587         This function releases an attribute from use.  Further use of the
1588     attribute ID will result in undefined behavior.
1589 --------------------------------------------------------------------------*/
1590 herr_t
H5Aclose(hid_t attr_id)1591 H5Aclose(hid_t attr_id)
1592 {
1593     herr_t ret_value = SUCCEED;   /* Return value */
1594 
1595     FUNC_ENTER_API(FAIL)
1596     H5TRACE1("e", "i", attr_id);
1597 
1598     /* check arguments */
1599     if(NULL == H5I_object_verify(attr_id, H5I_ATTR))
1600         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
1601 
1602     /* Decrement references to that atom (and close it) */
1603     if(H5I_dec_app_ref(attr_id) < 0)
1604         HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute")
1605 
1606 done:
1607     FUNC_LEAVE_API(ret_value)
1608 } /* H5Aclose() */
1609 
1610 
1611 /*-------------------------------------------------------------------------
1612  * Function:	H5Aexists
1613  *
1614  * Purpose:	Checks if an attribute with a given name exists on an opened
1615  *              object.
1616  *
1617  * Return:	Success:	TRUE/FALSE
1618  * 		Failure:	Negative
1619  *
1620  * Programmer:	Quincey Koziol
1621  *              Thursday, November 1, 2007
1622  *
1623  *-------------------------------------------------------------------------
1624  */
1625 htri_t
H5Aexists(hid_t obj_id,const char * attr_name)1626 H5Aexists(hid_t obj_id, const char *attr_name)
1627 {
1628     H5G_loc_t   loc;                    /* Object location */
1629     htri_t	ret_value;              /* Return value */
1630 
1631     FUNC_ENTER_API(FAIL)
1632     H5TRACE2("t", "i*s", obj_id, attr_name);
1633 
1634     /* check arguments */
1635     if(H5I_ATTR == H5I_get_type(obj_id))
1636 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1637     if(H5G_loc(obj_id, &loc) < 0)
1638 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1639     if(!attr_name || !*attr_name)
1640 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
1641 
1642     /* Check if the attribute exists */
1643     if((ret_value = H5O_attr_exists(loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0)
1644         HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
1645 
1646 done:
1647     FUNC_LEAVE_API(ret_value)
1648 } /* H5Aexists() */
1649 
1650 
1651 /*-------------------------------------------------------------------------
1652  * Function:	H5Aexists_by_name
1653  *
1654  * Purpose:	Checks if an attribute with a given name exists on an object.
1655  *
1656  * Return:	Success:	TRUE/FALSE
1657  * 		Failure:	Negative
1658  *
1659  * Programmer:	Quincey Koziol
1660  *              Thursday, November 1, 2007
1661  *
1662  *-------------------------------------------------------------------------
1663  */
1664 htri_t
H5Aexists_by_name(hid_t loc_id,const char * obj_name,const char * attr_name,hid_t lapl_id)1665 H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
1666     hid_t lapl_id)
1667 {
1668     H5G_loc_t   loc;                    /* Object location */
1669     htri_t	ret_value;              /* Return value */
1670 
1671     FUNC_ENTER_API(FAIL)
1672     H5TRACE4("t", "i*s*si", loc_id, obj_name, attr_name, lapl_id);
1673 
1674     /* check arguments */
1675     if(H5I_ATTR == H5I_get_type(loc_id))
1676 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
1677     if(H5G_loc(loc_id, &loc) < 0)
1678 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
1679     if(!obj_name || !*obj_name)
1680 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
1681     if(!attr_name || !*attr_name)
1682 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
1683     if(H5P_DEFAULT == lapl_id)
1684         lapl_id = H5P_LINK_ACCESS_DEFAULT;
1685     else
1686         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
1687             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
1688 
1689     if((ret_value = H5A_exists_by_name(loc, obj_name, attr_name, lapl_id, H5AC_ind_dxpl_id)) < 0)
1690         HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
1691 
1692 done:
1693     FUNC_LEAVE_API(ret_value)
1694 } /* H5Aexists_by_name() */
1695 
1696