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