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