1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /* Programmer:  Quincey Koziol <koziol@ncsa.uiuc.edu>
15  *
16  * Purpose:	Generic Property Functions
17  */
18 
19 /****************/
20 /* Module Setup */
21 /****************/
22 
23 #include "H5Pmodule.h"          /* This source code file is part of the H5P module */
24 
25 
26 /***********/
27 /* Headers */
28 /***********/
29 #include "H5private.h"		/* Generic Functions			*/
30 #include "H5Eprivate.h"		/* Error handling		  	*/
31 #include "H5Iprivate.h"		/* IDs			  		*/
32 #include "H5Ppkg.h"		/* Property lists		  	*/
33 
34 /****************/
35 /* Local Macros */
36 /****************/
37 
38 
39 /******************/
40 /* Local Typedefs */
41 /******************/
42 
43 /* Typedef for property iterator callback */
44 typedef struct {
45     H5P_iterate_t iter_func;    /* Iterator callback */
46     hid_t id;                   /* Property list or class ID */
47     void *iter_data;            /* Iterator callback pointer */
48 } H5P_iter_ud_t;
49 
50 
51 /********************/
52 /* Local Prototypes */
53 /********************/
54 
55 
56 /*********************/
57 /* Package Variables */
58 /*********************/
59 
60 /* Package initialization variable */
61 hbool_t H5_PKG_INIT_VAR = FALSE;
62 
63 
64 /*****************************/
65 /* Library Private Variables */
66 /*****************************/
67 
68 
69 /*******************/
70 /* Local Variables */
71 /*******************/
72 
73 
74 /*--------------------------------------------------------------------------
75  NAME
76     H5Pcopy
77  PURPOSE
78     Routine to copy a property list or class
79  USAGE
80     hid_t H5Pcopy(id)
81         hid_t id;           IN: Property list or class ID to copy
82  RETURNS
83     Success: valid property list ID on success (non-negative)
84     Failure: negative
85  DESCRIPTION
86     Copy a property list or class and return the ID.  This routine calls the
87     class 'copy' callback after any property 'copy' callbacks are called
88     (assuming all property 'copy' callbacks return successfully).
89 
90  GLOBAL VARIABLES
91  COMMENTS, BUGS, ASSUMPTIONS
92  EXAMPLES
93  REVISION LOG
94 --------------------------------------------------------------------------*/
95 hid_t
H5Pcopy(hid_t id)96 H5Pcopy(hid_t id)
97 {
98     void *obj;                  /* Property object to copy */
99     hid_t ret_value=FALSE;      /* return value */
100 
101     FUNC_ENTER_API(FAIL)
102     H5TRACE1("i", "i", id);
103 
104     if(H5P_DEFAULT==id)
105         HGOTO_DONE(H5P_DEFAULT);
106 
107     /* Check arguments. */
108     if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
109         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property object");
110     if(NULL == (obj = H5I_object(id)))
111         HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
112 
113     /* Compare property lists */
114     if(H5I_GENPROP_LST == H5I_get_type(id)) {
115         if((ret_value = H5P_copy_plist((H5P_genplist_t *)obj, TRUE)) < 0)
116             HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property list");
117     } /* end if */
118     /* Must be property classes */
119     else {
120         H5P_genclass_t *copy_class;      /* Copy of class */
121 
122         /* Copy the class */
123         if((copy_class = H5P_copy_pclass((H5P_genclass_t *)obj)) == NULL)
124             HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property class");
125 
126         /* Get an atom for the copied class */
127         if((ret_value = H5I_register(H5I_GENPROP_CLS, copy_class, TRUE)) < 0) {
128             H5P_close_class(copy_class);
129             HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
130         } /* end if */
131     } /* end else */
132 
133 done:
134     FUNC_LEAVE_API(ret_value)
135 }   /* H5Pcopy() */
136 
137 
138 /*--------------------------------------------------------------------------
139  NAME
140     H5Pcreate_class
141  PURPOSE
142     Create a new property list class.
143  USAGE
144     hid_t H5Pcreate_class(parent, name, cls_create, create_data,
145                 cls_close, close_data)
146         hid_t parent;       IN: Property list class ID of parent class
147         const char *name;   IN: Name of class we are creating
148         H5P_cls_create_func_t cls_create;   IN: The callback function to call
149                                     when each property list in this class is
150                                     created.
151         void *create_data;  IN: Pointer to user data to pass along to class
152                                     creation callback.
153         H5P_cls_copy_func_t cls_copy;   IN: The callback function to call
154                                     when each property list in this class is
155                                     copied.
156         void *copy_data;  IN: Pointer to user data to pass along to class
157                                     copy callback.
158         H5P_cls_close_func_t cls_close;     IN: The callback function to call
159                                     when each property list in this class is
160                                     closed.
161         void *close_data;   IN: Pointer to user data to pass along to class
162                                     close callback.
163  RETURNS
164     Returns a valid property list class ID on success, NULL on failure.
165  DESCRIPTION
166     Allocates memory and attaches a class to the property list class hierarchy.
167  GLOBAL VARIABLES
168  COMMENTS, BUGS, ASSUMPTIONS
169  EXAMPLES
170  REVISION LOG
171 --------------------------------------------------------------------------*/
172 hid_t
H5Pcreate_class(hid_t parent,const char * name,H5P_cls_create_func_t cls_create,void * create_data,H5P_cls_copy_func_t cls_copy,void * copy_data,H5P_cls_close_func_t cls_close,void * close_data)173 H5Pcreate_class(hid_t parent, const char *name,
174     H5P_cls_create_func_t cls_create, void *create_data,
175     H5P_cls_copy_func_t cls_copy, void *copy_data,
176     H5P_cls_close_func_t cls_close, void *close_data
177     )
178 {
179     H5P_genclass_t	*par_class = NULL;  /* Pointer to the parent class */
180     H5P_genclass_t	*pclass = NULL;     /* Property list class created */
181     hid_t	ret_value;                  /* Return value		   */
182 
183     FUNC_ENTER_API(FAIL)
184     H5TRACE8("i", "i*sx*xx*xx*x", parent, name, cls_create, create_data, cls_copy,
185              copy_data, cls_close, close_data);
186 
187     /* Check arguments. */
188     if(H5P_DEFAULT!=parent && (H5I_GENPROP_CLS!=H5I_get_type(parent)))
189         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
190     if(!name || !*name)
191         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name")
192     if((create_data != NULL && cls_create == NULL)
193             || (copy_data != NULL && cls_copy == NULL)
194             || (close_data != NULL && cls_close == NULL))
195         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data specified, but no callback provided")
196 
197     /* Get the pointer to the parent class */
198     if(parent == H5P_DEFAULT)
199         par_class = NULL;
200     else if(NULL == (par_class = (H5P_genclass_t *)H5I_object(parent)))
201         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class")
202 
203     /* Create the new property list class */
204     if(NULL == (pclass = H5P_create_class(par_class, name, H5P_TYPE_USER, cls_create, create_data, cls_copy, copy_data, cls_close, close_data)))
205         HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class")
206 
207     /* Get an atom for the class */
208     if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass, TRUE)) < 0)
209         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class")
210 
211 done:
212     if(ret_value < 0 && pclass)
213         H5P_close_class(pclass);
214 
215     FUNC_LEAVE_API(ret_value)
216 }   /* H5Pcreate_class() */
217 
218 
219 /*--------------------------------------------------------------------------
220  NAME
221     H5Pcreate
222  PURPOSE
223     Routine to create a new property list of a property list class.
224  USAGE
225     hid_t H5Pcreate(cls_id)
226         hid_t cls_id;       IN: Property list class create list from
227  RETURNS
228     Returns a valid property list ID on success, FAIL on failure.
229  DESCRIPTION
230         Creates a property list of a given class.  If a 'create' callback
231     exists for the property list class, it is called before the
232     property list is passed back to the user.  If 'create' callbacks exist for
233     any individual properties in the property list, they are called before the
234     class 'create' callback.
235 
236  GLOBAL VARIABLES
237  COMMENTS, BUGS, ASSUMPTIONS
238  EXAMPLES
239  REVISION LOG
240 --------------------------------------------------------------------------*/
241 hid_t
H5Pcreate(hid_t cls_id)242 H5Pcreate(hid_t cls_id)
243 {
244     H5P_genclass_t	*pclass;   /* Property list class to modify */
245     hid_t ret_value;               /* return value */
246 
247     FUNC_ENTER_API(FAIL)
248     H5TRACE1("i", "i", cls_id);
249 
250     /* Check arguments. */
251     if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
252         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
253 
254     /* Create the new property list */
255     if((ret_value = H5P_create_id(pclass, TRUE)) < 0)
256         HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list");
257 
258 done:
259     FUNC_LEAVE_API(ret_value)
260 }   /* H5Pcreate() */
261 
262 
263 /*--------------------------------------------------------------------------
264  NAME
265     H5Pregister2
266  PURPOSE
267     Routine to register a new property in a property list class.
268  USAGE
269     herr_t H5Pregister2(class, name, size, default, prp_create, prp_set, prp_get, prp_close)
270         hid_t class;            IN: Property list class to close
271         const char *name;       IN: Name of property to register
272         size_t size;            IN: Size of property in bytes
273         void *def_value;        IN: Pointer to buffer containing default value
274                                     for property in newly created property lists
275         H5P_prp_create_func_t prp_create;   IN: Function pointer to property
276                                     creation callback
277         H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
278         H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
279         H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
280         H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
281         H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
282         H5P_prp_close_func_t prp_close; IN: Function pointer to property close
283                                     callback
284  RETURNS
285     Returns non-negative on success, negative on failure.
286  DESCRIPTION
287         Registers a new property with a property list class.  The property will
288     exist in all property list objects of that class after this routine is
289     finished.  The name of the property must not already exist.  The default
290     property value must be provided and all new property lists created with this
291     property will have the property value set to the default provided.  Any of
292     the callback routines may be set to NULL if they are not needed.
293 
294         Zero-sized properties are allowed and do not store any data in the
295     property list.  These may be used as flags to indicate the presence or
296     absence of a particular piece of information.  The 'default' pointer for a
297     zero-sized property may be set to NULL.  The property 'create' & 'close'
298     callbacks are called for zero-sized properties, but the 'set' and 'get'
299     callbacks are never called.
300 
301         The 'create' callback is called when a new property list with this
302     property is being created.  H5P_prp_create_func_t is defined as:
303         typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name,
304                 size_t size, void *initial_value);
305     where the parameters to the callback function are:
306         hid_t prop_id;      IN: The ID of the property list being created.
307         const char *name;   IN: The name of the property being modified.
308         size_t size;        IN: The size of the property value
309         void *initial_value; IN/OUT: The initial value for the property being created.
310                                 (The 'default' value passed to H5Pregister2)
311     The 'create' routine may modify the value to be set and those changes will
312     be stored as the initial value of the property.  If the 'create' routine
313     returns a negative value, the new property value is not copied into the
314     property and the property list creation routine returns an error value.
315 
316         The 'set' callback is called before a new value is copied into the
317     property.  H5P_prp_set_func_t is defined as:
318         typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
319             size_t size, void *value);
320     where the parameters to the callback function are:
321         hid_t prop_id;      IN: The ID of the property list being modified.
322         const char *name;   IN: The name of the property being modified.
323         size_t size;        IN: The size of the property value
324         void *new_value;    IN/OUT: The value being set for the property.
325     The 'set' routine may modify the value to be set and those changes will be
326     stored as the value of the property.  If the 'set' routine returns a
327     negative value, the new property value is not copied into the property and
328     the property list set routine returns an error value.
329 
330         The 'get' callback is called before a value is retrieved from the
331     property.  H5P_prp_get_func_t is defined as:
332         typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
333             size_t size, void *value);
334     where the parameters to the callback function are:
335         hid_t prop_id;      IN: The ID of the property list being queried.
336         const char *name;   IN: The name of the property being queried.
337         size_t size;        IN: The size of the property value
338         void *value;        IN/OUT: The value being retrieved for the property.
339     The 'get' routine may modify the value to be retrieved and those changes
340     will be returned to the calling function.  If the 'get' routine returns a
341     negative value, the property value is returned and the property list get
342     routine returns an error value.
343 
344         The 'delete' callback is called when a property is deleted from a
345     property list.  H5P_prp_del_func_t is defined as:
346         typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
347             size_t size, void *value);
348     where the parameters to the callback function are:
349         hid_t prop_id;      IN: The ID of the property list the property is deleted from.
350         const char *name;   IN: The name of the property being deleted.
351         size_t size;        IN: The size of the property value
352         void *value;        IN/OUT: The value of the property being deleted.
353     The 'delete' routine may modify the value passed in, but the value is not
354     used by the library when the 'delete' routine returns.  If the
355     'delete' routine returns a negative value, the property list deletion
356     routine returns an error value but the property is still deleted.
357 
358         The 'copy' callback is called when a property list with this
359     property is copied.  H5P_prp_copy_func_t is defined as:
360         typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
361             void *value);
362     where the parameters to the callback function are:
363         const char *name;   IN: The name of the property being copied.
364         size_t size;        IN: The size of the property value
365         void *value;        IN: The value of the property being copied.
366     The 'copy' routine may modify the value to be copied and those changes will be
367     stored as the value of the property.  If the 'copy' routine returns a
368     negative value, the new property value is not copied into the property and
369     the property list copy routine returns an error value.
370 
371         The 'compare' callback is called when a property list with this
372     property is compared to another property list.  H5P_prp_compare_func_t is
373     defined as:
374         typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
375             size_t size);
376     where the parameters to the callback function are:
377         const void *value1; IN: The value of the first property being compared.
378         const void *value2; IN: The value of the second property being compared.
379         size_t size;        IN: The size of the property value
380     The 'compare' routine may not modify the values to be compared.  The
381     'compare' routine should return a positive value if VALUE1 is greater than
382     VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1
383     and VALUE2 are equal.
384 
385         The 'close' callback is called when a property list with this
386     property is being destroyed.  H5P_prp_close_func_t is defined as:
387         typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
388             void *value);
389     where the parameters to the callback function are:
390         const char *name;   IN: The name of the property being closed.
391         size_t size;        IN: The size of the property value
392         void *value;        IN: The value of the property being closed.
393     The 'close' routine may modify the value passed in, but the value is not
394     used by the library when the 'close' routine returns.  If the
395     'close' routine returns a negative value, the property list close
396     routine returns an error value but the property list is still closed.
397 
398  GLOBAL VARIABLES
399  COMMENTS, BUGS, ASSUMPTIONS
400         The 'set' callback function may be useful to range check the value being
401     set for the property or may perform some tranformation/translation of the
402     value set.  The 'get' callback would then [probably] reverse the
403     transformation, etc.  A single 'get' or 'set' callback could handle
404     multiple properties by performing different actions based on the property
405     name or other properties in the property list.
406 
407         I would like to say "the property list is not closed" when a 'close'
408     routine fails, but I don't think that's possible due to other properties in
409     the list being successfully closed & removed from the property list.  I
410     suppose that it would be possible to just remove the properties which have
411     successful 'close' callbacks, but I'm not happy with the ramifications
412     of a mangled, un-closable property list hanging around...  Any comments? -QAK
413 
414  EXAMPLES
415  REVISION LOG
416 --------------------------------------------------------------------------*/
417 herr_t
H5Pregister2(hid_t cls_id,const char * name,size_t size,void * def_value,H5P_prp_create_func_t prp_create,H5P_prp_set_func_t prp_set,H5P_prp_get_func_t prp_get,H5P_prp_delete_func_t prp_delete,H5P_prp_copy_func_t prp_copy,H5P_prp_compare_func_t prp_cmp,H5P_prp_close_func_t prp_close)418 H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value,
419     H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
420     H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_delete,
421     H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp,
422     H5P_prp_close_func_t prp_close)
423 {
424     H5P_genclass_t *pclass;     /* Property list class to modify */
425     H5P_genclass_t *orig_pclass; /* Original property class */
426     herr_t ret_value;           /* Return value */
427 
428     FUNC_ENTER_API(FAIL)
429     H5TRACE11("e", "i*sz*xxxxxxxx", cls_id, name, size, def_value, prp_create,
430              prp_set, prp_get, prp_delete, prp_copy, prp_cmp, prp_close);
431 
432     /* Check arguments. */
433     if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(cls_id, H5I_GENPROP_CLS)))
434         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
435     if(!name || !*name)
436         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name")
437     if(size > 0 && def_value == NULL)
438         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default")
439 
440     /* Create the new property list class */
441     orig_pclass = pclass;
442     if((ret_value = H5P_register(&pclass, name, size, def_value, prp_create, prp_set, prp_get, NULL, NULL, prp_delete, prp_copy, prp_cmp, prp_close)) < 0)
443         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class")
444 
445     /* Check if the property class changed and needs to be substituted in the ID */
446     if(pclass != orig_pclass) {
447         H5P_genclass_t *old_pclass;     /* Old property class */
448 
449         /* Substitute the new property class in the ID */
450         if(NULL == (old_pclass = (H5P_genclass_t *)H5I_subst(cls_id, pclass)))
451             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to substitute property class in ID")
452         HDassert(old_pclass == orig_pclass);
453 
454         /* Close the previous class */
455         if(H5P_close_class(old_pclass) < 0)
456             HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close original property class after substitution")
457     } /* end if */
458 
459 done:
460     FUNC_LEAVE_API(ret_value)
461 }   /* H5Pregister2() */
462 
463 
464 /*--------------------------------------------------------------------------
465  NAME
466     H5Pinsert2
467  PURPOSE
468     Routine to insert a new property in a property list.
469  USAGE
470     herr_t H5Pinsert2(plist, name, size, value, prp_set, prp_get, prp_close)
471         hid_t plist;            IN: Property list to add property to
472         const char *name;       IN: Name of property to add
473         size_t size;            IN: Size of property in bytes
474         void *value;            IN: Pointer to the value for the property
475         H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback
476         H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback
477         H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback
478         H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback
479         H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback
480         H5P_prp_close_func_t prp_close; IN: Function pointer to property close
481                                     callback
482  RETURNS
483     Returns non-negative on success, negative on failure.
484  DESCRIPTION
485         Inserts a temporary property into a property list.  The property will
486     exist only in this property list object.  The name of the property must not
487     already exist.  The value must be provided unless the property is zero-
488     sized.  Any of the callback routines may be set to NULL if they are not
489     needed.
490 
491         Zero-sized properties are allowed and do not store any data in the
492     property list.  These may be used as flags to indicate the presence or
493     absence of a particular piece of information.  The 'value' pointer for a
494     zero-sized property may be set to NULL.  The property 'close' callback is
495     called for zero-sized properties, but the 'set' and 'get' callbacks are
496     never called.
497 
498         The 'set' callback is called before a new value is copied into the
499     property.  H5P_prp_set_func_t is defined as:
500         typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
501             size_t size, void *value);
502     where the parameters to the callback function are:
503         hid_t prop_id;      IN: The ID of the property list being modified.
504         const char *name;   IN: The name of the property being modified.
505         size_t size;        IN: The size of the property value
506         void *new_value;    IN/OUT: The value being set for the property.
507     The 'set' routine may modify the value to be set and those changes will be
508     stored as the value of the property.  If the 'set' routine returns a
509     negative value, the new property value is not copied into the property and
510     the property list set routine returns an error value.
511 
512         The 'get' callback is called before a value is retrieved from the
513     property.  H5P_prp_get_func_t is defined as:
514         typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
515             size_t size, void *value);
516     where the parameters to the callback function are:
517         hid_t prop_id;      IN: The ID of the property list being queried.
518         const char *name;   IN: The name of the property being queried.
519         size_t size;        IN: The size of the property value
520         void *value;        IN/OUT: The value being retrieved for the property.
521     The 'get' routine may modify the value to be retrieved and those changes
522     will be returned to the calling function.  If the 'get' routine returns a
523     negative value, the property value is returned and the property list get
524     routine returns an error value.
525 
526         The 'delete' callback is called when a property is deleted from a
527     property list.  H5P_prp_del_func_t is defined as:
528         typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
529             size_t size, void *value);
530     where the parameters to the callback function are:
531         hid_t prop_id;      IN: The ID of the property list the property is deleted from.
532         const char *name;   IN: The name of the property being deleted.
533         size_t size;        IN: The size of the property value
534         void *value;        IN/OUT: The value of the property being deleted.
535     The 'delete' routine may modify the value passed in, but the value is not
536     used by the library when the 'delete' routine returns.  If the
537     'delete' routine returns a negative value, the property list deletion
538     routine returns an error value but the property is still deleted.
539 
540         The 'copy' callback is called when a property list with this
541     property is copied.  H5P_prp_copy_func_t is defined as:
542         typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
543             void *value);
544     where the parameters to the callback function are:
545         const char *name;   IN: The name of the property being copied.
546         size_t size;        IN: The size of the property value
547         void *value;        IN: The value of the property being copied.
548     The 'copy' routine may modify the value to be copied and those changes will be
549     stored as the value of the property.  If the 'copy' routine returns a
550     negative value, the new property value is not copied into the property and
551     the property list copy routine returns an error value.
552 
553         The 'compare' callback is called when a property list with this
554     property is compared to another property list.  H5P_prp_compare_func_t is
555     defined as:
556         typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
557             size_t size);
558     where the parameters to the callback function are:
559         const void *value1; IN: The value of the first property being compared.
560         const void *value2; IN: The value of the second property being compared.
561         size_t size;        IN: The size of the property value
562     The 'compare' routine may not modify the values to be compared.  The
563     'compare' routine should return a positive value if VALUE1 is greater than
564     VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1
565     and VALUE2 are equal.
566 
567         The 'close' callback is called when a property list with this
568     property is being destroyed.  H5P_prp_close_func_t is defined as:
569         typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
570             void *value);
571     where the parameters to the callback function are:
572         const char *name;   IN: The name of the property being closed.
573         size_t size;        IN: The size of the property value
574         void *value;        IN: The value of the property being closed.
575     The 'close' routine may modify the value passed in, but the value is not
576     used by the library when the 'close' routine returns.  If the
577     'close' routine returns a negative value, the property list close
578     routine returns an error value but the property list is still closed.
579 
580  GLOBAL VARIABLES
581  COMMENTS, BUGS, ASSUMPTIONS
582         The 'set' callback function may be useful to range check the value being
583     set for the property or may perform some tranformation/translation of the
584     value set.  The 'get' callback would then [probably] reverse the
585     transformation, etc.  A single 'get' or 'set' callback could handle
586     multiple properties by performing different actions based on the property
587     name or other properties in the property list.
588 
589         There is no 'create' callback routine for temporary property list
590     objects, the initial value is assumed to have any necessary setup already
591     performed on it.
592 
593         I would like to say "the property list is not closed" when a 'close'
594     routine fails, but I don't think that's possible due to other properties in
595     the list being successfully closed & removed from the property list.  I
596     suppose that it would be possible to just remove the properties which have
597     successful 'close' callbacks, but I'm not happy with the ramifications
598     of a mangled, un-closable property list hanging around...  Any comments? -QAK
599 
600  EXAMPLES
601  REVISION LOG
602 --------------------------------------------------------------------------*/
603 herr_t
H5Pinsert2(hid_t plist_id,const char * name,size_t size,void * value,H5P_prp_set_func_t prp_set,H5P_prp_get_func_t prp_get,H5P_prp_delete_func_t prp_delete,H5P_prp_copy_func_t prp_copy,H5P_prp_compare_func_t prp_cmp,H5P_prp_close_func_t prp_close)604 H5Pinsert2(hid_t plist_id, const char *name, size_t size, void *value,
605     H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
606     H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
607     H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close)
608 {
609     H5P_genplist_t	*plist;    /* Property list to modify */
610     herr_t ret_value;           /* return value */
611 
612     FUNC_ENTER_API(FAIL)
613     H5TRACE10("e", "i*sz*xxxxxxx", plist_id, name, size, value, prp_set, prp_get,
614              prp_delete, prp_copy, prp_cmp, prp_close);
615 
616     /* Check arguments. */
617     if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
618         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
619     if(!name || !*name)
620         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name")
621     if(size > 0 && value == NULL)
622         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default")
623 
624     /* Create the new property list class */
625     if((ret_value = H5P_insert(plist, name, size, value, prp_set, prp_get,
626             NULL, NULL, prp_delete, prp_copy, prp_cmp, prp_close)) < 0)
627         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in plist")
628 
629 done:
630     FUNC_LEAVE_API(ret_value)
631 }   /* H5Pinsert2() */
632 
633 
634 /*--------------------------------------------------------------------------
635  NAME
636     H5Pset
637  PURPOSE
638     Routine to set a property's value in a property list.
639  USAGE
640     herr_t H5Pset(plist_id, name, value)
641         hid_t plist_id;         IN: Property list to find property in
642         const char *name;       IN: Name of property to set
643         void *value;            IN: Pointer to the value for the property
644  RETURNS
645     Returns non-negative on success, negative on failure.
646  DESCRIPTION
647         Sets a new value for a property in a property list.  The property name
648     must exist or this routine will fail.  If there is a 'set' callback routine
649     registered for this property, the 'value' will be passed to that routine and
650     any changes to the 'value' will be used when setting the property value.
651     The information pointed at by the 'value' pointer (possibly modified by the
652     'set' callback) is copied into the property list value and may be changed
653     by the application making the H5Pset call without affecting the property
654     value.
655 
656         If the 'set' callback routine returns an error, the property value will
657     not be modified.  This routine may not be called for zero-sized properties
658     and will return an error in that case.
659 
660  GLOBAL VARIABLES
661  COMMENTS, BUGS, ASSUMPTIONS
662  EXAMPLES
663  REVISION LOG
664 --------------------------------------------------------------------------*/
665 herr_t
H5Pset(hid_t plist_id,const char * name,const void * value)666 H5Pset(hid_t plist_id, const char *name, const void *value)
667 {
668     H5P_genplist_t *plist;      /* Property list to modify */
669     herr_t ret_value = SUCCEED; /* return value */
670 
671     FUNC_ENTER_API(FAIL)
672     H5TRACE3("e", "i*s*x", plist_id, name, value);
673 
674     /* Check arguments. */
675     if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
676         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
677     if(!name || !*name)
678         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
679     if(value == NULL)
680         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value");
681 
682     /* Go set the value */
683     if(H5P_set(plist, name, value) < 0)
684         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to set value in plist");
685 
686 done:
687     FUNC_LEAVE_API(ret_value)
688 }   /* H5Pset() */
689 
690 
691 /*--------------------------------------------------------------------------
692  NAME
693     H5Pexist
694  PURPOSE
695     Routine to query the existance of a property in a property object.
696  USAGE
697     htri_t H5P_exist(id, name)
698         hid_t id;           IN: Property object ID to check
699         const char *name;   IN: Name of property to check for
700  RETURNS
701     Success: Positive if the property exists in the property object, zero
702             if the property does not exist.
703     Failure: negative value
704  DESCRIPTION
705         This routine checks if a property exists within a property list or
706     class.
707 
708  GLOBAL VARIABLES
709  COMMENTS, BUGS, ASSUMPTIONS
710  EXAMPLES
711  REVISION LOG
712 --------------------------------------------------------------------------*/
713 htri_t
H5Pexist(hid_t id,const char * name)714 H5Pexist(hid_t id, const char *name)
715 {
716     H5P_genplist_t	*plist;    /* Property list to query */
717     H5P_genclass_t	*pclass;   /* Property class to query */
718     htri_t ret_value;           /* return value */
719 
720     FUNC_ENTER_API(FAIL)
721     H5TRACE2("t", "i*s", id, name);
722 
723     /* Check arguments. */
724     if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
725         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
726     if(!name || !*name)
727         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
728 
729     /* Check for the existance of the property in the list or class */
730     if(H5I_GENPROP_LST == H5I_get_type(id)) {
731         if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
732             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
733         if((ret_value = H5P_exist_plist(plist, name)) < 0)
734             HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in list");
735     } /* end if */
736     else
737         if(H5I_GENPROP_CLS == H5I_get_type(id)) {
738             if(NULL == (pclass = (H5P_genclass_t *)H5I_object(id)))
739                 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
740             if((ret_value = H5P_exist_pclass(pclass, name)) < 0)
741                 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in class");
742         } /* end if */
743         else
744             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
745 
746 done:
747     FUNC_LEAVE_API(ret_value)
748 }   /* H5Pexist() */
749 
750 
751 /*--------------------------------------------------------------------------
752  NAME
753     H5Pget_size
754  PURPOSE
755     Routine to query the size of a property in a property list or class.
756  USAGE
757     herr_t H5Pget_size(id, name)
758         hid_t id;               IN: ID of property list or class to check
759         const char *name;       IN: Name of property to query
760         size_t *size;           OUT: Size of property
761  RETURNS
762     Success: non-negative value
763     Failure: negative value
764  DESCRIPTION
765         This routine retrieves the size of a property's value in bytes.  Zero-
766     sized properties are allowed and return a value of 0.  This function works
767     for both property lists and classes.
768 
769  GLOBAL VARIABLES
770  COMMENTS, BUGS, ASSUMPTIONS
771  EXAMPLES
772  REVISION LOG
773 --------------------------------------------------------------------------*/
774 herr_t
H5Pget_size(hid_t id,const char * name,size_t * size)775 H5Pget_size(hid_t id, const char *name, size_t *size)
776 {
777     H5P_genclass_t	*pclass;   /* Property class to query */
778     H5P_genplist_t	*plist;    /* Property list to query */
779     herr_t ret_value;           /* return value */
780 
781     FUNC_ENTER_API(FAIL)
782     H5TRACE3("e", "i*s*z", id, name, size);
783 
784     /* Check arguments. */
785     if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
786         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
787     if(!name || !*name)
788         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
789     if(size==NULL)
790         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property size");
791 
792     if(H5I_GENPROP_LST == H5I_get_type(id)) {
793         if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
794             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
795 
796         /* Check the property size */
797         if((ret_value = H5P_get_size_plist(plist, name, size)) < 0)
798             HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist");
799     } /* end if */
800     else
801         if(H5I_GENPROP_CLS == H5I_get_type(id)) {
802             if(NULL == (pclass = (H5P_genclass_t *)H5I_object(id)))
803                 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
804 
805             /* Check the property size */
806             if((ret_value = H5P_get_size_pclass(pclass, name, size)) < 0)
807                 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist");
808         } /* end if */
809         else
810             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
811 
812 done:
813     FUNC_LEAVE_API(ret_value)
814 }   /* H5Pget_size() */
815 
816 
817 /*--------------------------------------------------------------------------
818  NAME
819     H5Pencode
820  PURPOSE
821     Routine to convert the property values in a property list into a binary buffer
822  USAGE
823     herr_t H5Pencode(plist_id, buf, nalloc)
824         hid_t plist_id;         IN: Identifier to property list to encode
825         void *buf:              OUT: buffer to gold the encoded plist
826         size_t *nalloc;         IN/OUT: size of buffer needed to encode plist
827  RETURNS
828     Returns non-negative on success, negative on failure.
829  DESCRIPTION
830     Encodes a property list into a binary buffer. If the buffer is NULL, then
831     the call will set the size needed to encode the plist in nalloc. Otherwise
832     the routine will encode the plist in buf.
833  GLOBAL VARIABLES
834  COMMENTS, BUGS, ASSUMPTIONS
835  EXAMPLES
836  REVISION LOG
837 --------------------------------------------------------------------------*/
838 herr_t
H5Pencode(hid_t plist_id,void * buf,size_t * nalloc)839 H5Pencode(hid_t plist_id, void *buf, size_t *nalloc)
840 {
841     H5P_genplist_t	*plist;         /* Property list to query */
842     herr_t ret_value = SUCCEED;          /* return value */
843 
844     FUNC_ENTER_API(FAIL)
845     H5TRACE3("e", "i*x*z", plist_id, buf, nalloc);
846 
847     /* Check arguments. */
848     if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
849         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
850 
851     /* Call the internal encode routine */
852     if((ret_value = H5P__encode(plist, TRUE, buf, nalloc)) < 0)
853         HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to encode property list");
854 
855 done:
856     FUNC_LEAVE_API(ret_value)
857 }   /* H5Pencode() */
858 
859 
860 /*--------------------------------------------------------------------------
861  NAME
862     H5Pdecode
863  PURPOSE
864     API routine to decode a property list from a binary buffer.
865  USAGE
866     hid_t H5Pdecode(buf)
867         void *buf;    IN: buffer that holds the encoded plist
868  RETURNS
869     Returns non-negative ID of new property list object on success, negative
870         on failure.
871  DESCRIPTION
872      Decodes a property list from a binary buffer. The contents of the buffer
873      contain the values for the correponding properties of the plist. The decode
874      callback of a certain property decodes its value from the buffer and sets it
875      in the property list.
876  GLOBAL VARIABLES
877  COMMENTS, BUGS, ASSUMPTIONS
878      Properties in the property list that are not encoded in the serialized
879      form retain their default value.
880  EXAMPLES
881  REVISION LOG
882 --------------------------------------------------------------------------*/
883 hid_t
H5Pdecode(const void * buf)884 H5Pdecode(const void *buf)
885 {
886     hid_t ret_value = SUCCEED;          /* return value */
887 
888     FUNC_ENTER_API(FAIL)
889     H5TRACE1("i", "*x", buf);
890 
891     /* Call the internal decode routine */
892     if((ret_value = H5P__decode(buf)) < 0)
893         HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "unable to decode property list");
894 
895 done:
896     FUNC_LEAVE_API(ret_value)
897 }   /* H5Pdecode() */
898 
899 
900 /*--------------------------------------------------------------------------
901  NAME
902     H5Pget_class
903  PURPOSE
904     Routine to query the class of a generic property list
905  USAGE
906     hid_t H5Pget_class(plist_id)
907         hid_t plist_id;         IN: Property list to query
908  RETURNS
909     Success: ID of class object
910     Failure: negative
911  DESCRIPTION
912     This routine retrieves the class of a property list.
913 
914  GLOBAL VARIABLES
915  COMMENTS, BUGS, ASSUMPTIONS
916     Change the name of this function to H5Pget_class (and remove old H5Pget_class)
917  EXAMPLES
918  REVISION LOG
919 --------------------------------------------------------------------------*/
920 hid_t
H5Pget_class(hid_t plist_id)921 H5Pget_class(hid_t plist_id)
922 {
923     H5P_genplist_t	*plist;         /* Property list to query */
924     H5P_genclass_t	*pclass=NULL;   /* Property list class */
925     hid_t ret_value=FAIL;           /* return value */
926 
927     FUNC_ENTER_API(FAIL)
928     H5TRACE1("i", "i", plist_id);
929 
930     /* Check arguments. */
931     if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
932         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
933 
934     /* Retrieve the property list class */
935     if((pclass = H5P_get_class(plist)) == NULL)
936         HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list");
937 
938     /* Increment the outstanding references to the class object */
939     if(H5P_access_class(pclass, H5P_MOD_INC_REF) < 0)
940         HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count");
941 
942     /* Get an atom for the class */
943     if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass, TRUE)) < 0)
944         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class");
945 
946 done:
947     if(ret_value<0 && pclass)
948         H5P_close_class(pclass);
949 
950     FUNC_LEAVE_API(ret_value)
951 }   /* H5Pget_class() */
952 
953 
954 /*--------------------------------------------------------------------------
955  NAME
956     H5Pget_nprops
957  PURPOSE
958     Routine to query the size of a property in a property list or class.
959  USAGE
960     herr_t H5Pget_nprops(id, nprops)
961         hid_t id;               IN: ID of Property list or class to check
962         size_t *nprops;         OUT: Number of properties in the property object
963  RETURNS
964     Success: non-negative value
965     Failure: negative value
966  DESCRIPTION
967         This routine retrieves the number of properties in a property list or
968     class.  If a property class ID is given, the number of registered properties
969     in the class is returned in NPROPS.  If a property list ID is given, the
970     current number of properties in the list is returned in NPROPS.
971 
972  GLOBAL VARIABLES
973  COMMENTS, BUGS, ASSUMPTIONS
974  EXAMPLES
975  REVISION LOG
976 --------------------------------------------------------------------------*/
977 herr_t
H5Pget_nprops(hid_t id,size_t * nprops)978 H5Pget_nprops(hid_t id, size_t *nprops)
979 {
980     H5P_genplist_t	*plist;    /* Property list to query */
981     H5P_genclass_t	*pclass;   /* Property class to query */
982     herr_t ret_value=SUCCEED;      /* return value */
983 
984     FUNC_ENTER_API(FAIL)
985     H5TRACE2("e", "i*z", id, nprops);
986 
987     /* Check arguments. */
988     if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
989         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
990     if(nprops==NULL)
991         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property nprops pointer");
992 
993     if(H5I_GENPROP_LST == H5I_get_type(id)) {
994         if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
995             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
996         if(H5P_get_nprops_plist(plist, nprops) < 0)
997             HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in plist");
998     } /* end if */
999     else
1000         if(H5I_GENPROP_CLS == H5I_get_type(id)) {
1001             if(NULL == (pclass = (H5P_genclass_t *)H5I_object(id)))
1002                 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
1003             if(H5P_get_nprops_pclass(pclass, nprops, FALSE) < 0)
1004                 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in pclass");
1005         } /* end if */
1006         else
1007             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
1008 
1009 done:
1010     FUNC_LEAVE_API(ret_value)
1011 }   /* H5Pget_nprops() */
1012 
1013 
1014 /*--------------------------------------------------------------------------
1015  NAME
1016     H5Pequal
1017  PURPOSE
1018     Routine to query whether two property lists or two property classes are equal
1019  USAGE
1020     htri_t H5Pequal(id1, id2)
1021         hid_t id1;         IN: Property list or class ID to compare
1022         hid_t id2;         IN: Property list or class ID to compare
1023  RETURNS
1024     Success: TRUE if equal, FALSE if unequal
1025     Failure: negative
1026  DESCRIPTION
1027     Determines whether two property lists or two property classes are equal.
1028 
1029  GLOBAL VARIABLES
1030  COMMENTS, BUGS, ASSUMPTIONS
1031  EXAMPLES
1032  REVISION LOG
1033 --------------------------------------------------------------------------*/
1034 htri_t
H5Pequal(hid_t id1,hid_t id2)1035 H5Pequal(hid_t id1, hid_t id2)
1036 {
1037     void *obj1, *obj2;          /* Property objects to compare */
1038     htri_t ret_value = FALSE;     /* return value */
1039 
1040     FUNC_ENTER_API(FAIL)
1041     H5TRACE2("t", "ii", id1, id2);
1042 
1043     /* Check arguments. */
1044     if((H5I_GENPROP_LST != H5I_get_type(id1) && H5I_GENPROP_CLS != H5I_get_type(id1))
1045             || (H5I_GENPROP_LST != H5I_get_type(id2) && H5I_GENPROP_CLS != H5I_get_type(id2)))
1046         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects")
1047     if(H5I_get_type(id1) != H5I_get_type(id2))
1048         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects")
1049     if(NULL == (obj1 = H5I_object(id1)) || NULL == (obj2 = H5I_object(id2)))
1050         HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist")
1051 
1052     /* Compare property lists */
1053     if(H5I_GENPROP_LST == H5I_get_type(id1)) {
1054         int cmp_ret = 0;
1055 
1056         if(H5P_cmp_plist((const H5P_genplist_t *)obj1, (const H5P_genplist_t *)obj2, &cmp_ret) < 0)
1057             HGOTO_ERROR(H5E_PLIST, H5E_CANTCOMPARE, FAIL, "can't compare property lists")
1058 
1059         /* Set return value */
1060         ret_value = cmp_ret == 0 ? TRUE : FALSE;
1061     } /* end if */
1062     /* Must be property classes */
1063     else {
1064         if(H5P_cmp_class((const H5P_genclass_t *)obj1, (const H5P_genclass_t *)obj2) == 0)
1065             ret_value = TRUE;
1066     } /* end else */
1067 
1068 done:
1069     FUNC_LEAVE_API(ret_value)
1070 }   /* H5Pequal() */
1071 
1072 
1073 /*--------------------------------------------------------------------------
1074  NAME
1075     H5Pisa_class
1076  PURPOSE
1077     Routine to query whether a property list is a certain class
1078  USAGE
1079     hid_t H5Pisa_class(plist_id, pclass_id)
1080         hid_t plist_id;         IN: Property list to query
1081         hid_t pclass_id;        IN: Property class to query
1082  RETURNS
1083     Success: TRUE (1) or FALSE (0)
1084     Failure: negative
1085  DESCRIPTION
1086     This routine queries whether a property list is a member of the property
1087     list class.
1088 
1089  GLOBAL VARIABLES
1090  COMMENTS, BUGS, ASSUMPTIONS
1091     What about returning a value indicating that the property class is further
1092     up the class hierarchy?
1093  EXAMPLES
1094  REVISION LOG
1095 --------------------------------------------------------------------------*/
1096 htri_t
H5Pisa_class(hid_t plist_id,hid_t pclass_id)1097 H5Pisa_class(hid_t plist_id, hid_t pclass_id)
1098 {
1099     htri_t ret_value;                   /* return value */
1100 
1101     FUNC_ENTER_API(FAIL)
1102     H5TRACE2("t", "ii", plist_id, pclass_id);
1103 
1104     /* Check arguments. */
1105     if(H5I_GENPROP_LST != H5I_get_type(plist_id))
1106         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
1107     if(H5I_GENPROP_CLS != H5I_get_type(pclass_id))
1108         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class");
1109 
1110     /* Compare the property list's class against the other class */
1111     if((ret_value = H5P_isa_class(plist_id, pclass_id)) < 0)
1112         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes");
1113 
1114 done:
1115     FUNC_LEAVE_API(ret_value)
1116 }   /* H5Pisa_class() */
1117 
1118 
1119 /*--------------------------------------------------------------------------
1120  NAME
1121     H5P__iterate_cb
1122  PURPOSE
1123     Internal callback routine when iterating over properties in property list
1124     or class
1125  USAGE
1126     int H5P__iterate_cb(prop, udata)
1127         H5P_genprop_t *prop;        IN: Pointer to the property
1128         void *udata;                IN/OUT: Pointer to iteration data from user
1129  RETURNS
1130     Success: Returns the return value of the last call to ITER_FUNC
1131     Failure: negative value
1132  DESCRIPTION
1133     This routine calls the actual callback routine for the property in the
1134 property list or class.
1135  GLOBAL VARIABLES
1136  COMMENTS, BUGS, ASSUMPTIONS
1137  EXAMPLES
1138  REVISION LOG
1139 --------------------------------------------------------------------------*/
1140 static int
H5P__iterate_cb(H5P_genprop_t * prop,void * _udata)1141 H5P__iterate_cb(H5P_genprop_t *prop, void *_udata)
1142 {
1143     H5P_iter_ud_t *udata = (H5P_iter_ud_t *)_udata;     /* Pointer to user data */
1144     int ret_value = 0;                                  /* Return value */
1145 
1146     FUNC_ENTER_STATIC_NOERR
1147 
1148     /* Sanity check */
1149     HDassert(prop);
1150     HDassert(udata);
1151 
1152     /* Call the user's callback routine */
1153     ret_value = (*udata->iter_func)(udata->id, prop->name, udata->iter_data);
1154 
1155     FUNC_LEAVE_NOAPI(ret_value)
1156 } /* end H5P__iterate_cb() */
1157 
1158 
1159 /*--------------------------------------------------------------------------
1160  NAME
1161     H5Piterate
1162  PURPOSE
1163     Routine to iterate over the properties in a property list or class
1164  USAGE
1165     int H5Piterate(pclass_id, idx, iter_func, iter_data)
1166         hid_t id;                   IN: ID of property object to iterate over
1167         int *idx;                   IN/OUT: Index of the property to begin with
1168         H5P_iterate_t iter_func;    IN: Function pointer to function to be
1169                                         called with each property iterated over.
1170         void *iter_data;            IN/OUT: Pointer to iteration data from user
1171  RETURNS
1172     Success: Returns the return value of the last call to ITER_FUNC if it was
1173                 non-zero, or zero if all properties have been processed.
1174     Failure: negative value
1175  DESCRIPTION
1176     This routine iterates over the properties in the property object specified
1177 with ID.  The properties in both property lists and classes may be iterated
1178 over with this function.  For each property in the object, the ITER_DATA and
1179 some additional information, specified below, are passed to the ITER_FUNC
1180 function.  The iteration begins with the IDX property in the object and the
1181 next element to be processed by the operator is returned in IDX.  If IDX is
1182 NULL, then the iterator starts at the first property; since no stopping point
1183 is returned in this case, the iterator cannot be restarted if one of the calls
1184 to its operator returns non-zero.  The IDX value is 0-based (ie. to start at
1185 the "first" property, the IDX value should be 0).
1186 
1187 The prototype for H5P_iterate_t is:
1188     typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
1189 The operation receives the property list or class identifier for the object
1190 being iterated over, ID, the name of the current property within the object,
1191 NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA.
1192 
1193 The return values from an operator are:
1194     Zero causes the iterator to continue, returning zero when all properties
1195         have been processed.
1196     Positive causes the iterator to immediately return that positive value,
1197         indicating short-circuit success. The iterator can be restarted at the
1198         index of the next property.
1199     Negative causes the iterator to immediately return that value, indicating
1200         failure. The iterator can be restarted at the index of the next
1201         property.
1202 
1203 H5Piterate assumes that the properties in the object identified by ID remains
1204 unchanged through the iteration.  If the membership changes during the
1205 iteration, the function's behavior is undefined.
1206 
1207  GLOBAL VARIABLES
1208  COMMENTS, BUGS, ASSUMPTIONS
1209  EXAMPLES
1210  REVISION LOG
1211 --------------------------------------------------------------------------*/
1212 int
H5Piterate(hid_t id,int * idx,H5P_iterate_t iter_func,void * iter_data)1213 H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data)
1214 {
1215     H5P_iter_ud_t udata;    /* User data for internal iterator callback */
1216     int fake_idx = 0;       /* Index when user doesn't provide one */
1217     void *obj;              /* Property object to copy */
1218     int ret_value;          /* return value */
1219 
1220     FUNC_ENTER_API(FAIL)
1221     H5TRACE4("Is", "i*Isx*x", id, idx, iter_func, iter_data);
1222 
1223     /* Check arguments. */
1224     if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id))
1225         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
1226     if(NULL == (obj = H5I_object(id)))
1227         HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist");
1228     if(iter_func == NULL)
1229         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration callback");
1230 
1231     /* Set up user data */
1232     udata.iter_func = iter_func;
1233     udata.id = id;
1234     udata.iter_data = iter_data;
1235 
1236     if(H5I_GENPROP_LST == H5I_get_type(id)) {
1237         /* Iterate over a property list */
1238         if((ret_value = H5P_iterate_plist((H5P_genplist_t *)obj, TRUE, (idx ? idx : &fake_idx), H5P__iterate_cb, &udata)) < 0)
1239             HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over list");
1240     } /* end if */
1241     else
1242         if(H5I_GENPROP_CLS == H5I_get_type(id)) {
1243             /* Iterate over a property class */
1244             if((ret_value = H5P_iterate_pclass((H5P_genclass_t *)obj, (idx ? idx : &fake_idx), H5P__iterate_cb, &udata)) < 0)
1245                 HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over class");
1246         } /* end if */
1247         else
1248             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object");
1249 
1250 done:
1251     FUNC_LEAVE_API(ret_value)
1252 }   /* H5Piterate() */
1253 
1254 
1255 /*--------------------------------------------------------------------------
1256  NAME
1257     H5Pget
1258  PURPOSE
1259     Routine to query the value of a property in a property list.
1260  USAGE
1261     herr_t H5Pget(plist_id, name, value)
1262         hid_t plist_id;         IN: Property list to check
1263         const char *name;       IN: Name of property to query
1264         void *value;            OUT: Pointer to the buffer for the property value
1265  RETURNS
1266     Returns non-negative on success, negative on failure.
1267  DESCRIPTION
1268         Retrieves a copy of the value for a property in a property list.  The
1269     property name must exist or this routine will fail.  If there is a
1270     'get' callback routine registered for this property, the copy of the
1271     value of the property will first be passed to that routine and any changes
1272     to the copy of the value will be used when returning the property value
1273     from this routine.
1274         If the 'get' callback routine returns an error, 'value' will not be
1275     modified and this routine will return an error.  This routine may not be
1276     called for zero-sized properties.
1277 
1278  GLOBAL VARIABLES
1279  COMMENTS, BUGS, ASSUMPTIONS
1280  EXAMPLES
1281  REVISION LOG
1282 --------------------------------------------------------------------------*/
1283 herr_t
H5Pget(hid_t plist_id,const char * name,void * value)1284 H5Pget(hid_t plist_id, const char *name, void *value)
1285 {
1286     H5P_genplist_t *plist;      /* Property list pointer */
1287     herr_t ret_value=SUCCEED;   /* return value */
1288 
1289     FUNC_ENTER_API(FAIL)
1290     H5TRACE3("e", "i*s*x", plist_id, name, value);
1291 
1292     /* Check arguments. */
1293     if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
1294         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
1295     if(!name || !*name)
1296         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
1297     if(value==NULL)
1298         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value");
1299 
1300     /* Go get the value */
1301     if(H5P_get(plist,name,value) < 0)
1302         HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value");
1303 
1304 done:
1305     FUNC_LEAVE_API(ret_value)
1306 }   /* H5Pget() */
1307 
1308 
1309 /*--------------------------------------------------------------------------
1310  NAME
1311     H5Premove
1312  PURPOSE
1313     Routine to remove a property from a property list.
1314  USAGE
1315     herr_t H5Premove(plist_id, name)
1316         hid_t plist_id;         IN: Property list to modify
1317         const char *name;       IN: Name of property to remove
1318  RETURNS
1319     Returns non-negative on success, negative on failure.
1320  DESCRIPTION
1321         Removes a property from a property list.  Both properties which were
1322     in existance when the property list was created (i.e. properties registered
1323     with H5Pregister2) and properties added to the list after it was created
1324     (i.e. added with H5Pinsert2) may be removed from a property list.
1325     Properties do not need to be removed a property list before the list itself
1326     is closed, they will be released automatically when H5Pclose is called.
1327     The 'close' callback for this property is called before the property is
1328     release, if the callback exists.
1329 
1330  GLOBAL VARIABLES
1331  COMMENTS, BUGS, ASSUMPTIONS
1332  EXAMPLES
1333  REVISION LOG
1334 --------------------------------------------------------------------------*/
1335 herr_t
H5Premove(hid_t plist_id,const char * name)1336 H5Premove(hid_t plist_id, const char *name)
1337 {
1338     H5P_genplist_t	*plist;    /* Property list to modify */
1339     herr_t ret_value;           /* return value */
1340 
1341     FUNC_ENTER_API(FAIL)
1342     H5TRACE2("e", "i*s", plist_id, name);
1343 
1344     /* Check arguments. */
1345     if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST)))
1346         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
1347     if(!name || !*name)
1348         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
1349 
1350     /* Create the new property list class */
1351     if((ret_value = H5P_remove(plist, name)) < 0)
1352         HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property");
1353 
1354 done:
1355     FUNC_LEAVE_API(ret_value)
1356 }   /* H5Premove() */
1357 
1358 
1359 /*--------------------------------------------------------------------------
1360  NAME
1361     H5Pcopy_prop
1362  PURPOSE
1363     Routine to copy a property from one list or class to another
1364  USAGE
1365     herr_t H5Pcopy_prop(dst_id, src_id, name)
1366         hid_t dst_id;               IN: ID of destination property list or class
1367         hid_t src_id;               IN: ID of source property list or class
1368         const char *name;           IN: Name of property to copy
1369  RETURNS
1370     Success: non-negative value.
1371     Failure: negative value.
1372  DESCRIPTION
1373     Copies a property from one property list or class to another.
1374 
1375     If a property is copied from one class to another, all the property
1376     information will be first deleted from the destination class and then the
1377     property information will be copied from the source class into the
1378     destination class.
1379 
1380     If a property is copied from one list to another, the property will be
1381     first deleted from the destination list (generating a call to the 'close'
1382     callback for the property, if one exists) and then the property is copied
1383     from the source list to the destination list (generating a call to the
1384     'copy' callback for the property, if one exists).
1385 
1386     If the property does not exist in the destination class or list, this call
1387     is equivalent to calling H5Pregister2 or H5Pinsert2 (for a class or list, as
1388     appropriate) and the 'create' callback will be called in the case of the
1389     property being copied into a list (if such a callback exists for the
1390     property).
1391 
1392  GLOBAL VARIABLES
1393  COMMENTS, BUGS, ASSUMPTIONS
1394  EXAMPLES
1395  REVISION LOG
1396 --------------------------------------------------------------------------*/
1397 herr_t
H5Pcopy_prop(hid_t dst_id,hid_t src_id,const char * name)1398 H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name)
1399 {
1400     H5I_type_t src_id_type, dst_id_type;        /* ID types */
1401     herr_t ret_value = SUCCEED;     /* return value */
1402 
1403     FUNC_ENTER_API(FAIL)
1404     H5TRACE3("e", "ii*s", dst_id, src_id, name);
1405 
1406     /* Check arguments. */
1407     if((src_id_type = H5I_get_type(src_id)) < 0)
1408         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid source ID")
1409     if((dst_id_type = H5I_get_type(dst_id)) < 0)
1410         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid destination ID")
1411     if((H5I_GENPROP_LST != src_id_type && H5I_GENPROP_CLS != src_id_type)
1412             || (H5I_GENPROP_LST != dst_id_type && H5I_GENPROP_CLS != dst_id_type))
1413         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects")
1414     if(src_id_type != dst_id_type)
1415         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects")
1416     if(!name || !*name)
1417         HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given")
1418 
1419     /* Compare property lists */
1420     if(H5I_GENPROP_LST == src_id_type) {
1421         if(H5P_copy_prop_plist(dst_id, src_id, name) < 0)
1422             HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between lists")
1423     } /* end if */
1424     /* Must be property classes */
1425     else {
1426         if(H5P_copy_prop_pclass(dst_id, src_id, name) < 0)
1427             HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between classes")
1428     } /* end else */
1429 
1430 done:
1431     FUNC_LEAVE_API(ret_value)
1432 }   /* H5Pcopy_prop() */
1433 
1434 
1435 /*--------------------------------------------------------------------------
1436  NAME
1437     H5Punregister
1438  PURPOSE
1439     Routine to remove a property from a property list class.
1440  USAGE
1441     herr_t H5Punregister(pclass_id, name)
1442         hid_t pclass_id;         IN: Property list class to modify
1443         const char *name;       IN: Name of property to remove
1444  RETURNS
1445     Returns non-negative on success, negative on failure.
1446  DESCRIPTION
1447         Removes a property from a property list class.  Future property lists
1448     created of that class will not contain this property.  Existing property
1449     lists containing this property are not affected.
1450 
1451  GLOBAL VARIABLES
1452  COMMENTS, BUGS, ASSUMPTIONS
1453  EXAMPLES
1454  REVISION LOG
1455 --------------------------------------------------------------------------*/
1456 herr_t
H5Punregister(hid_t pclass_id,const char * name)1457 H5Punregister(hid_t pclass_id, const char *name)
1458 {
1459     H5P_genclass_t	*pclass;   /* Property list class to modify */
1460     herr_t ret_value;           /* return value */
1461 
1462     FUNC_ENTER_API(FAIL)
1463     H5TRACE2("e", "i*s", pclass_id, name);
1464 
1465     /* Check arguments. */
1466     if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
1467         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
1468     if(!name || !*name)
1469         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name");
1470 
1471     /* Remove the property list from class */
1472     if((ret_value = H5P_unregister(pclass, name)) < 0)
1473         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to remove property from class");
1474 
1475 done:
1476     FUNC_LEAVE_API(ret_value)
1477 }   /* H5Punregister() */
1478 
1479 
1480 /*--------------------------------------------------------------------------
1481  NAME
1482     H5Pclose
1483  PURPOSE
1484     Routine to close a property list.
1485  USAGE
1486     herr_t H5Pclose(plist_id)
1487         hid_t plist_id;       IN: Property list to close
1488  RETURNS
1489     Returns non-negative on success, negative on failure.
1490  DESCRIPTION
1491         Closes a property list.  If a 'close' callback exists for the property
1492     list class, it is called before the property list is destroyed.  If 'close'
1493     callbacks exist for any individual properties in the property list, they are
1494     called after the class 'close' callback.
1495 
1496  GLOBAL VARIABLES
1497  COMMENTS, BUGS, ASSUMPTIONS
1498  EXAMPLES
1499  REVISION LOG
1500 --------------------------------------------------------------------------*/
1501 herr_t
H5Pclose(hid_t plist_id)1502 H5Pclose(hid_t plist_id)
1503 {
1504     herr_t ret_value = SUCCEED;      /* return value */
1505 
1506     FUNC_ENTER_API(FAIL)
1507     H5TRACE1("e", "i", plist_id);
1508 
1509     /* Allow default property lists to pass through without throwing an error */
1510     if(H5P_DEFAULT != plist_id) {
1511         /* Check arguments. */
1512         if(H5I_GENPROP_LST != H5I_get_type(plist_id))
1513             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
1514 
1515         /* Close the property list */
1516         if(H5I_dec_app_ref(plist_id) < 0)
1517             HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close")
1518     } /* end if */
1519 
1520 done:
1521     FUNC_LEAVE_API(ret_value)
1522 }   /* H5Pclose() */
1523 
1524 
1525 /*--------------------------------------------------------------------------
1526  NAME
1527     H5Pget_class_name
1528  PURPOSE
1529     Routine to query the name of a generic property list class
1530  USAGE
1531     char *H5Pget_class_name(pclass_id)
1532         hid_t pclass_id;         IN: Property class to query
1533  RETURNS
1534     Success: Pointer to a malloc'ed string containing the class name
1535     Failure: NULL
1536  DESCRIPTION
1537         This routine retrieves the name of a generic property list class.
1538     The pointer to the name must be free'd by the user for successful calls.
1539 
1540  GLOBAL VARIABLES
1541  COMMENTS, BUGS, ASSUMPTIONS
1542  EXAMPLES
1543  REVISION LOG
1544 --------------------------------------------------------------------------*/
1545 char *
H5Pget_class_name(hid_t pclass_id)1546 H5Pget_class_name(hid_t pclass_id)
1547 {
1548     H5P_genclass_t	*pclass;    /* Property class to query */
1549     char *ret_value;       /* return value */
1550 
1551     FUNC_ENTER_API(NULL)
1552     H5TRACE1("*s", "i", pclass_id);
1553 
1554     /* Check arguments. */
1555     if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
1556         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property class");
1557 
1558     /* Get the property list class name */
1559     if((ret_value = H5P_get_class_name(pclass)) == NULL)
1560         HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "unable to query name of class");
1561 
1562 done:
1563     FUNC_LEAVE_API(ret_value)
1564 }   /* H5Pget_class_name() */
1565 
1566 
1567 /*--------------------------------------------------------------------------
1568  NAME
1569     H5Pget_class_parent
1570  PURPOSE
1571     routine to query the parent class of a generic property class
1572  USAGE
1573     hid_t H5Pget_class_parent(pclass_id)
1574         hid_t pclass_id;         IN: Property class to query
1575  RETURNS
1576     Success: ID of parent class object
1577     Failure: NULL
1578  DESCRIPTION
1579     This routine retrieves an ID for the parent class of a property class.
1580 
1581  GLOBAL VARIABLES
1582  COMMENTS, BUGS, ASSUMPTIONS
1583  EXAMPLES
1584  REVISION LOG
1585 --------------------------------------------------------------------------*/
1586 hid_t
H5Pget_class_parent(hid_t pclass_id)1587 H5Pget_class_parent(hid_t pclass_id)
1588 {
1589     H5P_genclass_t	*pclass;    /* Property class to query */
1590     H5P_genclass_t	*parent = NULL;   /* Parent's property class */
1591     hid_t ret_value;       /* return value */
1592 
1593     FUNC_ENTER_API(FAIL)
1594     H5TRACE1("i", "i", pclass_id);
1595 
1596     /* Check arguments. */
1597     if(NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(pclass_id, H5I_GENPROP_CLS)))
1598         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class")
1599 
1600     /* Retrieve the property class's parent */
1601     if(NULL == (parent = H5P_get_class_parent(pclass)))
1602         HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list")
1603 
1604     /* Increment the outstanding references to the class object */
1605     if(H5P_access_class(parent, H5P_MOD_INC_REF) < 0)
1606         HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count")
1607 
1608     /* Get an atom for the class */
1609     if((ret_value = H5I_register(H5I_GENPROP_CLS, parent, TRUE)) < 0)
1610         HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class")
1611 
1612 done:
1613     if(ret_value < 0 && parent)
1614         H5P_close_class(parent);
1615 
1616     FUNC_LEAVE_API(ret_value)
1617 }   /* H5Pget_class_parent() */
1618 
1619 
1620 /*--------------------------------------------------------------------------
1621  NAME
1622     H5Pclose_class
1623  PURPOSE
1624     Close a property list class.
1625  USAGE
1626     herr_t H5Pclose_class(cls_id)
1627         hid_t cls_id;       IN: Property list class ID to class
1628 
1629  RETURNS
1630     Returns non-negative on success, negative on failure.
1631  DESCRIPTION
1632     Releases memory and de-attach a class from the property list class hierarchy.
1633  GLOBAL VARIABLES
1634  COMMENTS, BUGS, ASSUMPTIONS
1635  EXAMPLES
1636  REVISION LOG
1637 --------------------------------------------------------------------------*/
1638 herr_t
H5Pclose_class(hid_t cls_id)1639 H5Pclose_class(hid_t cls_id)
1640 {
1641     herr_t	ret_value = SUCCEED;    /* Return value			*/
1642 
1643     FUNC_ENTER_API(FAIL)
1644     H5TRACE1("e", "i", cls_id);
1645 
1646     /* Check arguments */
1647     if(H5I_GENPROP_CLS != H5I_get_type(cls_id))
1648         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
1649 
1650     /* Close the property list class */
1651     if(H5I_dec_app_ref(cls_id) < 0)
1652         HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close")
1653 
1654 done:
1655     FUNC_LEAVE_API(ret_value)
1656 }   /* H5Pclose_class() */
1657 
1658