From e5413fa795c68dda46c11aee4a3615f52377b0df Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 11 Oct 2007 16:09:42 -0500 Subject: [svn-r14202] Description: Move H5Pregister our of old "compat v1.6" section and add it to the versioned symbols. Add simple regression test for H5Pregister1() Split H5P.c source file into H5P/H5Pint/H5Pdeprec files. Tested on: FreeBSD/32 6.2 (duty) in debug mode FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Mac OS X/32 10.4.10 (amazon) in debug mode --- MANIFEST | 2 + fortran/src/H5Pf.c | 20 +- src/H5P.c | 6020 +++++++--------------------------------------------- src/H5Pdeprec.c | 276 +++ src/H5Pint.c | 4448 ++++++++++++++++++++++++++++++++++++++ src/H5Ppkg.h | 20 +- src/H5Pprivate.h | 11 +- src/H5Ppublic.h | 48 +- src/H5vers.txt | 1 + src/H5version.h | 15 + src/Makefile.am | 5 +- src/Makefile.in | 10 +- test/tgenprop.c | 536 ++--- 13 files changed, 5913 insertions(+), 5499 deletions(-) create mode 100644 src/H5Pdeprec.c create mode 100644 src/H5Pint.c diff --git a/MANIFEST b/MANIFEST index 589cb52..aaece99 100644 --- a/MANIFEST +++ b/MANIFEST @@ -628,11 +628,13 @@ ./src/H5P.c ./src/H5Pacpl.c ./src/H5Pdcpl.c +./src/H5Pdeprec.c ./src/H5Pdxpl.c ./src/H5Pfapl.c ./src/H5Pfcpl.c ./src/H5Pfmpl.c ./src/H5Pgcpl.c +./src/H5Pint.c ./src/H5Plapl.c ./src/H5Plcpl.c ./src/H5Pocpl.c diff --git a/fortran/src/H5Pf.c b/fortran/src/H5Pf.c index c3bd709..54f99d0 100644 --- a/fortran/src/H5Pf.c +++ b/fortran/src/H5Pf.c @@ -2278,7 +2278,7 @@ nh5pregisterc_c(hid_t_f *class, _fcd name, int_f *name_len, size_t_f *size, _fcd /*---------------------------------------------------------------------------- * Name: h5pregister_c - * Purpose: Call H5Pregister to registers a permanent property + * Purpose: Call H5Pregister2 to registers a permanent property * Inputs: class - property list class identifier * name - name of the new property * name_len - length of the "name" buffer @@ -2292,24 +2292,22 @@ nh5pregisterc_c(hid_t_f *class, _fcd name, int_f *name_len, size_t_f *size, _fcd int_f nh5pregister_c(hid_t_f *class, _fcd name, int_f *name_len, size_t_f *size, void UNUSED *value) { + char* c_name = NULL; int_f ret_value = -1; - hid_t c_class; - char* c_name; - size_t c_size; - c_name = (char *)HD5f2cstring(name, (size_t)*name_len); - if (c_name == NULL) goto DONE; - c_size = (size_t)*size; - c_class = (hid_t)*class; + if(NULL == (c_name = (char *)HD5f2cstring(name, (size_t)*name_len))) + goto DONE; /* - * Call H5Pregister function. + * Call H5Pregister2 function. */ - if( H5Pregister(c_class, c_name, c_size, value, NULL,NULL,NULL,NULL,NULL,NULL,NULL) <0) goto DONE; + if(H5Pregister2((hid_t)*class, c_name, (size_t)*size, value, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + goto DONE; ret_value = 0; DONE: - if(c_name != NULL) HDfree(c_name); + if(c_name != NULL) + HDfree(c_name); return ret_value; } diff --git a/src/H5P.c b/src/H5P.c index fa3d446..30b6913 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -25,189 +25,36 @@ #define H5P_PACKAGE /*suppress error about including H5Ppkg */ /* Interface initialization */ -#define H5_INTERFACE_INIT_FUNC H5P_init_interface +#define H5_INTERFACE_INIT_FUNC H5P_init_pub_interface /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* Files */ -#include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ -#include "H5Lprivate.h" /* Links */ -#include "H5MMprivate.h" /* Memory management */ #include "H5Ppkg.h" /* Property lists */ /****************/ /* Local Macros */ /****************/ -#define H5P_DEFAULT_SKIPLIST_HEIGHT 8 - /******************/ /* Local Typedefs */ /******************/ -/* Typedef for checking for duplicate class names in parent class */ -typedef struct { - const H5P_genclass_t *parent; /* Pointer to parent class */ - const char *name; /* Pointer to name to check */ -} H5P_check_class_t; - /********************/ /* Local Prototypes */ /********************/ -/* General helper routines */ -static herr_t H5P_unregister(H5P_genclass_t *pclass, const char *name); -static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type); -static herr_t H5P_free_prop(H5P_genprop_t *prop); - /*********************/ /* Package Variables */ /*********************/ -/* - * Predefined property list classes. These are initialized at runtime by - * H5P_init_interface() in this source file. - */ -hid_t H5P_CLS_ROOT_g = FAIL; -hid_t H5P_CLS_OBJECT_CREATE_g = FAIL; -hid_t H5P_CLS_FILE_CREATE_g = FAIL; -hid_t H5P_CLS_FILE_ACCESS_g = FAIL; -hid_t H5P_CLS_DATASET_CREATE_g = FAIL; -hid_t H5P_CLS_DATASET_ACCESS_g = FAIL; -hid_t H5P_CLS_DATASET_XFER_g = FAIL; -hid_t H5P_CLS_FILE_MOUNT_g = FAIL; -hid_t H5P_CLS_GROUP_CREATE_g = FAIL; -hid_t H5P_CLS_GROUP_ACCESS_g = FAIL; -hid_t H5P_CLS_DATATYPE_CREATE_g = FAIL; -hid_t H5P_CLS_DATATYPE_ACCESS_g = FAIL; -hid_t H5P_CLS_ATTRIBUTE_CREATE_g = FAIL; -hid_t H5P_CLS_OBJECT_COPY_g = FAIL; -hid_t H5P_CLS_LINK_CREATE_g = FAIL; -hid_t H5P_CLS_LINK_ACCESS_g = FAIL; -hid_t H5P_CLS_STRING_CREATE_g = FAIL; - -/* - * Predefined property lists for each predefined class. These are initialized - * at runtime by H5P_init_interface() in this source file. - */ -hid_t H5P_LST_FILE_CREATE_g = FAIL; -hid_t H5P_LST_FILE_ACCESS_g = FAIL; -hid_t H5P_LST_DATASET_CREATE_g = FAIL; -hid_t H5P_LST_DATASET_ACCESS_g = FAIL; -hid_t H5P_LST_DATASET_XFER_g = FAIL; -hid_t H5P_LST_FILE_MOUNT_g = FAIL; -hid_t H5P_LST_GROUP_CREATE_g = FAIL; -hid_t H5P_LST_GROUP_ACCESS_g = FAIL; -hid_t H5P_LST_DATATYPE_CREATE_g = FAIL; -hid_t H5P_LST_DATATYPE_ACCESS_g = FAIL; -hid_t H5P_LST_ATTRIBUTE_CREATE_g = FAIL; -hid_t H5P_LST_OBJECT_COPY_g = FAIL; -hid_t H5P_LST_LINK_CREATE_g = FAIL; -hid_t H5P_LST_LINK_ACCESS_g = FAIL; - -/* Root property list class library initialization object */ -const H5P_libclass_t H5P_CLS_ROOT[1] = {{ - "root", /* Class name for debugging */ - NULL, /* Parent class ID */ - &H5P_CLS_ROOT_g, /* Pointer to class ID */ - NULL, /* Pointer to default property list ID */ - NULL, /* Default property registration routine */ - NULL, /* Class creation callback */ - NULL, /* Class creation callback info */ - NULL, /* Class copy callback */ - NULL, /* Class copy callback info */ - NULL, /* Class close callback */ - NULL /* Class close callback info */ -}}; - -/* Group access property list class library initialization object */ -/* (move to proper source code file when used for real) */ -const H5P_libclass_t H5P_CLS_GACC[1] = {{ - "group access", /* Class name for debugging */ - &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */ - &H5P_CLS_GROUP_ACCESS_g, /* Pointer to class ID */ - &H5P_LST_GROUP_ACCESS_g, /* Pointer to default property list ID */ - NULL, /* Default property registration routine */ - NULL, /* Class creation callback */ - NULL, /* Class creation callback info */ - NULL, /* Class copy callback */ - NULL, /* Class copy callback info */ - NULL, /* Class close callback */ - NULL /* Class close callback info */ -}}; - -/* Dataset access property list class library initialization object */ -/* (move to proper source code file when used for real) */ -const H5P_libclass_t H5P_CLS_DACC[1] = {{ - "dataset access", /* Class name for debugging */ - &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */ - &H5P_CLS_DATASET_ACCESS_g, /* Pointer to class ID */ - &H5P_LST_DATASET_ACCESS_g, /* Pointer to default property list ID */ - NULL, /* Default property registration routine */ - NULL, /* Class creation callback */ - NULL, /* Class creation callback info */ - NULL, /* Class copy callback */ - NULL, /* Class copy callback info */ - NULL, /* Class close callback */ - NULL /* Class close callback info */ -}}; - -/* Datatype creation property list class library initialization object */ -/* (move to proper source code file when used for real) */ -const H5P_libclass_t H5P_CLS_TCRT[1] = {{ - "datatype create", /* Class name for debugging */ - &H5P_CLS_OBJECT_CREATE_g, /* Parent class ID */ - &H5P_CLS_DATATYPE_CREATE_g, /* Pointer to class ID */ - &H5P_LST_DATATYPE_CREATE_g, /* Pointer to default property list ID */ - NULL, /* Default property registration routine */ - NULL, /* Class creation callback */ - NULL, /* Class creation callback info */ - NULL, /* Class copy callback */ - NULL, /* Class copy callback info */ - NULL, /* Class close callback */ - NULL /* Class close callback info */ -}}; - -/* Datatype access property list class library initialization object */ -/* (move to proper source code file when used for real) */ -const H5P_libclass_t H5P_CLS_TACC[1] = {{ - "datatype access", /* Class name for debugging */ - &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */ - &H5P_CLS_DATATYPE_ACCESS_g, /* Pointer to class ID */ - &H5P_LST_DATATYPE_ACCESS_g, /* Pointer to default property list ID */ - NULL, /* Default property registration routine */ - NULL, /* Class creation callback */ - NULL, /* Class creation callback info */ - NULL, /* Class copy callback */ - NULL, /* Class copy callback info */ - NULL, /* Class close callback */ - NULL /* Class close callback info */ -}}; - - -/* Library property list classes defined in other code modules */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_OCRT[1]; /* Object creation */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_STRCRT[1]; /* String create */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_LACC[1]; /* Link access */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_GCRT[1]; /* Group create */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_OCPY[1]; /* Object copy */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_FCRT[1]; /* File creation */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_FACC[1]; /* File access */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_DCRT[1]; /* Dataset creation */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_DXFR[1]; /* Data transfer */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_FMNT[1]; /* File mount */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_ACRT[1]; /* Attribute creation */ -H5_DLLVAR const H5P_libclass_t H5P_CLS_LCRT[1]; /* Link creation */ - /*****************************/ /* Library Private Variables */ @@ -218,615 +65,26 @@ H5_DLLVAR const H5P_libclass_t H5P_CLS_LCRT[1]; /* Link creation */ /* Local Variables */ /*******************/ -/* Track the revision count of a class, to make comparisons faster */ -static unsigned H5P_next_rev = 0; -#define H5P_GET_NEXT_REV (H5P_next_rev++) - -/* List of all property list classes in the library */ -/* (order here is not important, they will be initialized in the proper - * order according to their parent class dependencies) - */ -static H5P_libclass_t const * const init_class[] = { - H5P_CLS_ROOT, /* Root */ - H5P_CLS_OCRT, /* Object create */ - H5P_CLS_STRCRT, /* String create */ - H5P_CLS_LACC, /* Link access */ - H5P_CLS_GCRT, /* Group create */ - H5P_CLS_OCPY, /* Object copy */ - H5P_CLS_GACC, /* Group access */ - H5P_CLS_FCRT, /* File creation */ - H5P_CLS_FACC, /* File access */ - H5P_CLS_DCRT, /* Dataset creation */ - H5P_CLS_DACC, /* Dataset access */ - H5P_CLS_DXFR, /* Data transfer */ - H5P_CLS_FMNT, /* File mount */ - H5P_CLS_TCRT, /* Datatype creation */ - H5P_CLS_TACC, /* Datatype access */ - H5P_CLS_ACRT, /* Attribute creation */ - H5P_CLS_LCRT /* Link creation */ -}; - -/* Declare a free list to manage the H5P_genclass_t struct */ -H5FL_DEFINE_STATIC(H5P_genclass_t); - -/* Declare a free list to manage the H5P_genprop_t struct */ -H5FL_DEFINE_STATIC(H5P_genprop_t); - -/* Declare a free list to manage the H5P_genplist_t struct */ -H5FL_DEFINE_STATIC(H5P_genplist_t); - - -/*-------------------------------------------------------------------------- - NAME - H5P_do_prop_cb1 - PURPOSE - Internal routine to call a property list callback routine and update - the property list accordingly. - USAGE - herr_t H5P_do_prop_cb1(slist,prop,cb) - H5SL_t *slist; IN/OUT: Skip list to hold changed properties - H5P_genprop_t *prop; IN: Property to call callback for - H5P_prp_cb1_t *cb; IN: Callback routine to call - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Calls the callback routine passed in. If the callback routine changes - the property value, then the property is duplicated and added to skip list. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb) -{ - void *tmp_value=NULL; /* Temporary value buffer */ - H5P_genprop_t *pcopy=NULL; /* Copy of property to insert into skip list */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_do_prop_cb1); - - /* Allocate space for a temporary copy of the property value */ - if (NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); - HDmemcpy(tmp_value,prop->value,prop->size); - - /* Call "type 1" callback ('create', 'copy' or 'close') */ - if(cb(prop->name,prop->size,tmp_value)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed"); - - /* Check if the property value changed */ - if(HDmemcmp(tmp_value,prop->value,prop->size)) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); - - /* Copy the changed value into the new property */ - HDmemcpy(pcopy->value,tmp_value,prop->size); - - /* Insert the changed property into the property list */ - if(H5P_add_prop(slist,pcopy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into skip list"); - } /* end if */ - -done: - /* Release the temporary value buffer */ - if(tmp_value!=NULL) - H5MM_xfree(tmp_value); - - /* Cleanup on failure */ - if(ret_value<0) { - if(pcopy!=NULL) - H5P_free_prop(pcopy); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5P_do_prop_cb1() */ - - -/*------------------------------------------------------------------------- - * Function: H5P_init - * - * Purpose: Initialize the interface from some other layer. - * - * Return: Success: non-negative - * - * Failure: negative - * - * Programmer: Quincey Koziol - * Saturday, March 4, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5P_init(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_init, FAIL) - /* FUNC_ENTER() does all the work */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_init() */ - /*-------------------------------------------------------------------------- NAME - H5P_init_interface -- Initialize interface-specific information + H5P_init_pub_interface -- Initialize interface-specific information USAGE - herr_t H5P_init_interface() + herr_t H5P_init_pub_interface() RETURNS Non-negative on success/Negative on failure DESCRIPTION - Initializes any interface-specific data or routines. ---------------------------------------------------------------------------*/ -static herr_t -H5P_init_interface(void) -{ - size_t tot_init; /* Total # of classes initialized */ - size_t pass_init; /* # of classes initialized in each pass */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_init_interface) - - /* - * Initialize the Generic Property class & object groups. - */ - if(H5I_register_type(H5I_GENPROP_CLS, (size_t)H5I_GENPROPCLS_HASHSIZE, 0, (H5I_free_t)H5P_close_class) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group") - if(H5I_register_type(H5I_GENPROP_LST, (size_t)H5I_GENPROPOBJ_HASHSIZE, 0, (H5I_free_t)H5P_close) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group") - - /* Repeatedly pass over the list of property list classes for the library, - * initializing each class if it's parent class is initialized, until no - * more progress is made. - */ - tot_init = 0; - do { - size_t u; /* Local index variable */ - - /* Reset pass initialization counter */ - pass_init = 0; - - /* Make a pass over all the library's property list classes */ - for(u = 0; u < NELMTS(init_class); u++) { - H5P_libclass_t const *lib_class = init_class[u]; /* Current class to operate on */ - - /* Check if the current class hasn't been initialized and can be now */ - HDassert(lib_class->class_id); - if(*lib_class->class_id == (-1) && (lib_class->par_class_id == NULL - || *lib_class->par_class_id > 0)) { - H5P_genclass_t *par_pclass = NULL; /* Parent class of new class */ - H5P_genclass_t *new_pclass; /* New property list class created */ - - /* Sanity check - only the root class is not allowed to have a parent class */ - HDassert(lib_class->par_class_id || lib_class == H5P_CLS_ROOT); - - /* Check for parent class */ - if(lib_class->par_class_id) { - /* Get the pointer to the parent class */ - if(NULL == (par_pclass = H5I_object(*lib_class->par_class_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") - } /* end if */ - - /* Allocate the new class */ - if(NULL == (new_pclass = H5P_create_class(par_pclass, lib_class->name, 1, lib_class->create_func, lib_class->create_data, lib_class->copy_func, lib_class->copy_data, lib_class->close_func, lib_class->close_data))) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed") - - /* Call routine to register properties for class */ - if(lib_class->reg_prop_func && (*lib_class->reg_prop_func)(new_pclass) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register properties") - - /* Register the new class */ - if((*lib_class->class_id = H5I_register(H5I_GENPROP_CLS, new_pclass)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class") - - /* Only register the default property list if it hasn't been created yet */ - if(lib_class->def_plist_id && *lib_class->def_plist_id == (-1)) { - /* Register the default property list for the new class*/ - if((*lib_class->def_plist_id = H5P_create_id(new_pclass)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list for class") - } /* end if */ - - /* Increment class initialization counters */ - pass_init++; - tot_init++; - } /* end if */ - } /* end for */ - } while(pass_init > 0); - - /* Verify that all classes were initialized */ - HDassert(tot_init == NELMTS(init_class)); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_init_interface() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_term_interface - PURPOSE - Terminate various H5P objects - USAGE - void H5P_term_interface() - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Release the atom group and any other resources allocated. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Can't report errors... - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -int -H5P_term_interface(void) -{ - int nlist=0; - int nclass=0; - int n=0; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_term_interface); - - if (H5_interface_initialize_g) { - /* Destroy HDF5 library property classes & lists */ - - /* Check if there are any open property list classes or lists */ - nclass = H5I_nmembers(H5I_GENPROP_CLS); - nlist = H5I_nmembers(H5I_GENPROP_LST); - n=nclass+nlist; - - /* If there are any open classes or groups, attempt to get rid of them. */ - if (n) { - /* Clear the lists */ - if(nlist>0) { - H5I_clear_type(H5I_GENPROP_LST, FALSE); - - /* Reset the default property lists, if they've been closed */ - if(H5I_nmembers(H5I_GENPROP_LST)==0) { - H5P_LST_FILE_CREATE_g = - H5P_LST_FILE_ACCESS_g = - H5P_LST_DATASET_CREATE_g = - H5P_LST_DATASET_ACCESS_g = - H5P_LST_DATASET_XFER_g = - H5P_LST_GROUP_CREATE_g = - H5P_LST_GROUP_ACCESS_g = - H5P_LST_DATATYPE_CREATE_g = - H5P_LST_DATATYPE_ACCESS_g = - H5P_LST_ATTRIBUTE_CREATE_g = - H5P_LST_OBJECT_COPY_g = - H5P_LST_LINK_CREATE_g = - H5P_LST_LINK_ACCESS_g = - H5P_LST_FILE_MOUNT_g = (-1); - } /* end if */ - } /* end if */ - - /* Only attempt to close the classes after all the lists are closed */ - if(nlist==0 && nclass>0) { - H5I_clear_type(H5I_GENPROP_CLS, FALSE); - - /* Reset the default property lists, if they've been closed */ - if(H5I_nmembers(H5I_GENPROP_CLS)==0) { - H5P_CLS_ROOT_g = - H5P_CLS_OBJECT_CREATE_g = - H5P_CLS_FILE_CREATE_g = - H5P_CLS_FILE_ACCESS_g = - H5P_CLS_DATASET_CREATE_g = - H5P_CLS_DATASET_ACCESS_g = - H5P_CLS_DATASET_XFER_g = - H5P_CLS_GROUP_CREATE_g = - H5P_CLS_GROUP_ACCESS_g = - H5P_CLS_DATATYPE_CREATE_g = - H5P_CLS_DATATYPE_ACCESS_g = - H5P_CLS_STRING_CREATE_g = - H5P_CLS_ATTRIBUTE_CREATE_g = - H5P_CLS_OBJECT_COPY_g = - H5P_CLS_LINK_CREATE_g = - H5P_CLS_LINK_ACCESS_g = - H5P_CLS_FILE_MOUNT_g = (-1); - } /* end if */ - } /* end if */ - } else { - H5I_dec_type_ref(H5I_GENPROP_LST); - n++; /*H5I*/ - H5I_dec_type_ref(H5I_GENPROP_CLS); - n++; /*H5I*/ - - H5_interface_initialize_g = 0; - } - } - FUNC_LEAVE_NOAPI(n); -} - - -/*-------------------------------------------------------------------------- - NAME - H5P_copy_pclass - PURPOSE - Internal routine to copy a generic property class - USAGE - hid_t H5P_copy_pclass(pclass) - H5P_genclass_t *pclass; IN: Property class to copy - RETURNS - Success: valid property class ID on success (non-negative) - Failure: negative - DESCRIPTION - Copy a property class and return the ID. This routine does not make - any callbacks. (They are only make when operating on property lists). - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5P_genclass_t * -H5P_copy_pclass(H5P_genclass_t *pclass) -{ - H5P_genclass_t *new_pclass = NULL; /* Property list class copied */ - H5P_genprop_t *pcopy; /* Copy of property to insert into class */ - H5P_genclass_t *ret_value=NULL; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_copy_pclass); - - assert(pclass); - - /* - * Create new property class object - */ - - /* Create the new property list class */ - if (NULL==(new_pclass=H5P_create_class(pclass->parent, pclass->name, 0, pclass->create_func, pclass->create_data, pclass->copy_func, pclass->copy_data, pclass->close_func, pclass->close_data))) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class"); - - /* Copy the properties registered for this class */ - if(pclass->nprops>0) { - H5SL_node_t *curr_node; /* Current node in skip list */ - - /* Walk through the properties in the old class */ - curr_node=H5SL_first(pclass->props); - while(curr_node!=NULL) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property"); - - /* Insert the initialized property into the property list */ - if(H5P_add_prop(new_pclass->props,pcopy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class"); - - /* Increment property count for class */ - new_pclass->nprops++; - - /* Get the next property node in the list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Set the return value */ - ret_value=new_pclass; - -done: - if (ret_value==NULL && new_pclass) - H5P_close_class(new_pclass); - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_copy_pclass() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_copy_plist - PURPOSE - Internal routine to copy a generic property list - USAGE - hid_t H5P_copy_plist(old_plist_id) - hid_t old_plist_id; IN: Property list ID to copy - RETURNS - Success: valid property list ID on success (non-negative) - Failure: negative - DESCRIPTION - Copy a property list and return the ID. This routine calls the - class 'copy' callback after any property 'copy' callbacks are called - (assuming all property 'copy' callbacks return successfully). + Initializes any interface-specific data or routines. (Just calls + H5P_init() currently). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG --------------------------------------------------------------------------*/ -hid_t -H5P_copy_plist(H5P_genplist_t *old_plist) +static herr_t +H5P_init_pub_interface(void) { - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genplist_t *new_plist=NULL; /* New property list generated from copy */ - H5P_genprop_t *tmp; /* Temporary pointer to properties */ - H5P_genprop_t *new_prop; /* New property created for copy */ - hid_t new_plist_id; /* Property list ID of new list created */ - H5SL_node_t *curr_node; /* Current node in skip list */ - H5SL_t *seen=NULL; /* Skip list containing properties already seen */ - size_t nseen; /* Number of items 'seen' */ - hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */ - hid_t ret_value=FAIL; /* return value */ - - FUNC_ENTER_NOAPI(H5P_copy_plist, FAIL); - - assert(old_plist); - - /* - * Create new property list object - */ - - /* Allocate room for the property list */ - if (NULL==(new_plist = H5FL_CALLOC(H5P_genplist_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,"memory allocation failed"); - - /* Set class state */ - new_plist->pclass = old_plist->pclass; - new_plist->nprops = 0; /* Initially the plist has the same number of properties as the class */ - new_plist->class_init = 0; /* Initially, wait until the class callback finishes to set */ - - /* Initialize the skip list to hold the changed properties */ - if((new_plist->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties"); - - /* Create the skip list for deleted properties */ - if((new_plist->del = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties"); - - /* Create the skip list to hold names of properties already seen - * (This prevents a property in the class hierarchy from having it's - * 'create' callback called, if a property in the class hierarchy has - * already been seen) - */ - if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT))== NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); - nseen = 0; - - /* Cycle through the deleted properties & copy them into the new list's deleted section */ - if(H5SL_count(old_plist->del)>0) { - curr_node=H5SL_first(old_plist->del); - while(curr_node) { - char *new_name; /* Pointer to new name */ - - /* Duplicate string for insertion into new deleted property skip list */ - if((new_name=H5MM_xstrdup((char *)H5SL_item(curr_node)))==NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); - - /* Insert property name into deleted list */ - if(H5SL_insert(new_plist->del,new_name,new_name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); - - /* Add property name to "seen" list */ - if(H5SL_insert(seen,new_name,new_name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); - nseen++; - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Cycle through the properties and copy them also */ - if(H5SL_count(old_plist->props)>0) { - curr_node=H5SL_first(old_plist->props); - while(curr_node) { - /* Get a pointer to the node's property */ - tmp=H5SL_item(curr_node); - - /* Make a copy of the list's property */ - if((new_prop=H5P_dup_prop(tmp,H5P_PROP_WITHIN_LIST))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); - - /* Call property copy callback, if it exists */ - if(new_prop->copy) { - if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value)<0) { - H5P_free_prop(new_prop); - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); - } /* end if */ - } /* end if */ - - /* Insert the initialized property into the property list */ - if(H5P_add_prop(new_plist->props,new_prop)<0) { - H5P_free_prop(new_prop); - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list"); - } /* end if */ - - /* Add property name to "seen" list */ - if(H5SL_insert(seen,new_prop->name,new_prop->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); - nseen++; - - /* Increment the number of properties in list */ - new_plist->nprops++; - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* - * Check for copying class properties (up through list of parent classes also), - * initialize each with default value & make property 'copy' callback. - */ - tclass=old_plist->pclass; - has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0); - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Walk through the properties in the old class */ - curr_node=H5SL_first(tclass->props); - while(curr_node!=NULL) { - /* Get pointer to property from node */ - tmp=H5SL_item(curr_node); - - /* Only "copy" properties we haven't seen before */ - if(nseen==0 || H5SL_search(seen,tmp->name)==NULL) { - /* Call property creation callback, if it exists */ - if(tmp->copy) { - /* Call the callback & insert changed value into skip list (if necessary) */ - if(H5P_do_prop_cb1(new_plist->props,tmp,tmp->copy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't create property"); - } /* end if */ - - /* Add property name to "seen" list, if we have other classes to work on */ - if(has_parent_class) { - if(H5SL_insert(seen,tmp->name,tmp->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); - nseen++; - } /* end if */ - - /* Increment the number of properties in list */ - new_plist->nprops++; - } /* end if */ - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* Increment the number of property lists derived from class */ - if(H5P_access_class(new_plist->pclass,H5P_MOD_INC_LST)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ref count"); - - /* Get an atom for the property list */ - if ((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list"); - - /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */ - new_plist->plist_id=new_plist_id; - - /* Call the class callback (if it exists) now that we have the property list ID */ - if(new_plist->pclass->copy_func!=NULL) { - if((new_plist->pclass->copy_func)(new_plist_id,old_plist->plist_id,old_plist->pclass->copy_data)<0) { - /* Delete ID, ignore return value */ - H5I_remove(new_plist_id); - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); - } /* end if */ - } /* end if */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_init_pub_interface) - /* Set the class initialization flag */ - new_plist->class_init=1; - - /* Set the return value */ - ret_value=new_plist_id; - -done: - /* Release the list of 'seen' properties */ - if(seen!=NULL) - H5SL_close(seen); - - if (ret_value<0 && new_plist) - H5P_close(new_plist); - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_copy_plist() */ + FUNC_LEAVE_NOAPI(H5P_init()) +} /* H5P_init_pub_interface() */ /*-------------------------------------------------------------------------- @@ -859,18 +117,18 @@ H5Pcopy(hid_t id) FUNC_ENTER_API(H5Pcopy, FAIL); H5TRACE1("i", "i", id); - if (H5P_DEFAULT==id) + if(H5P_DEFAULT==id) HGOTO_DONE(H5P_DEFAULT); /* Check arguments. */ - if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) + if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property object"); if(NULL == (obj = H5I_object(id))) HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist"); /* Compare property lists */ if(H5I_GENPROP_LST == H5I_get_type(id)) { - if((ret_value=H5P_copy_plist(obj))<0) + if((ret_value = H5P_copy_plist(obj)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property list"); } /* end if */ /* Must be property classes */ @@ -878,11 +136,11 @@ H5Pcopy(hid_t id) H5P_genclass_t *copy_class; /* Copy of class */ /* Copy the class */ - if((copy_class=H5P_copy_pclass(obj))==NULL) + if((copy_class = H5P_copy_pclass(obj)) == NULL) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property class"); /* Get an atom for the copied class */ - if ((ret_value = H5I_register(H5I_GENPROP_CLS, copy_class))<0) { + if((ret_value = H5I_register(H5I_GENPROP_CLS, copy_class)) < 0) { H5P_close_class(copy_class); HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); } /* end if */ @@ -895,113 +153,141 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_dup_prop + H5Pcreate_class PURPOSE - Internal routine to duplicate a property + Create a new property list class. USAGE - H5P_genprop_t *H5P_dup_prop(oprop) - H5P_genprop_t *oprop; IN: Pointer to property to copy - H5P_prop_within_t type; IN: Type of object the property will be inserted into + hid_t H5Pcreate_class(parent, name, cls_create, create_data, + cls_close, close_data) + hid_t parent; IN: Property list class ID of parent class + const char *name; IN: Name of class we are creating + H5P_cls_create_func_t cls_create; IN: The callback function to call + when each property list in this class is + created. + void *create_data; IN: Pointer to user data to pass along to class + creation callback. + H5P_cls_copy_func_t cls_copy; IN: The callback function to call + when each property list in this class is + copied. + void *copy_data; IN: Pointer to user data to pass along to class + copy callback. + H5P_cls_close_func_t cls_close; IN: The callback function to call + when each property list in this class is + closed. + void *close_data; IN: Pointer to user data to pass along to class + close callback. RETURNS - Returns a pointer to the newly created duplicate of a property on success, - NULL on failure. + Returns a valid property list class ID on success, NULL on failure. DESCRIPTION - Allocates memory and copies property information into a new property object. + Allocates memory and attaches a class to the property list class hierarchy. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static H5P_genprop_t * -H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type) +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 + ) { - H5P_genprop_t *prop=NULL; /* Pointer to new property copied */ - H5P_genprop_t *ret_value; /* Return value */ + H5P_genclass_t *par_class = NULL; /* Pointer to the parent class */ + H5P_genclass_t *pclass = NULL; /* Property list class created */ + hid_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_dup_prop); + FUNC_ENTER_API(H5Pcreate_class, FAIL); + H5TRACE8("i", "i*sx*xx*xx*x", parent, name, cls_create, create_data, cls_copy, + copy_data, cls_close, close_data); - assert(oprop); - assert(type!=H5P_PROP_WITHIN_UNKNOWN); + /* Check arguments. */ + if(H5P_DEFAULT!=parent && (H5I_GENPROP_CLS!=H5I_get_type(parent))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); + if((create_data!=NULL && cls_create==NULL) + || (copy_data!=NULL && cls_copy==NULL) + || (close_data!=NULL && cls_close==NULL)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data specified, but no callback provided"); - /* Allocate the new property */ - if (NULL==(prop = H5FL_MALLOC (H5P_genprop_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + /* Get the pointer to the parent class */ + if(parent==H5P_DEFAULT) + par_class=NULL; + else if(NULL == (par_class = H5I_object(parent))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class"); - /* Copy basic property information */ - HDmemcpy(prop,oprop,sizeof(H5P_genprop_t)); + /* Create the new property list class */ + if(NULL==(pclass=H5P_create_class(par_class, name, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class"); - /* Check if we should duplicate the name or share it */ + /* Get an atom for the class */ + if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); - /* Duplicating property for a class */ - if(type==H5P_PROP_WITHIN_CLASS) { - assert(oprop->type==H5P_PROP_WITHIN_CLASS); - assert(oprop->shared_name==0); +done: + if(ret_value<0 && pclass) + H5P_close_class(pclass); - /* Duplicate name */ - prop->name = H5MM_xstrdup(oprop->name); - } /* end if */ - /* Duplicating property for a list */ - else { - /* Check if we are duplicating a property from a list or a class */ + FUNC_LEAVE_API(ret_value); +} /* H5Pcreate_class() */ - /* Duplicating a property from a list */ - if(oprop->type==H5P_PROP_WITHIN_LIST) { - /* If the old property's name wasn't shared, we have to copy it here also */ - if(!oprop->shared_name) - prop->name = H5MM_xstrdup(oprop->name); - } /* end if */ - /* Duplicating a property from a class */ - else { - assert(oprop->type==H5P_PROP_WITHIN_CLASS); - assert(oprop->shared_name==0); + +/*-------------------------------------------------------------------------- + NAME + H5Pcreate + PURPOSE + Routine to create a new property list of a property list class. + USAGE + hid_t H5Pcreate(cls_id) + hid_t cls_id; IN: Property list class create list from + RETURNS + Returns a valid property list ID on success, FAIL on failure. + DESCRIPTION + Creates a property list of a given class. If a 'create' callback + exists for the property list class, it is called before the + property list is passed back to the user. If 'create' callbacks exist for + any individual properties in the property list, they are called before the + class 'create' callback. - /* Share the name */ - prop->shared_name=1; + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hid_t +H5Pcreate(hid_t cls_id) +{ + H5P_genclass_t *pclass; /* Property list class to modify */ + hid_t ret_value; /* return value */ - /* Set the type */ - prop->type=type; - } /* end else */ - } /* end else */ + FUNC_ENTER_API(H5Pcreate, FAIL); + H5TRACE1("i", "i", cls_id); - /* Duplicate current value, if it exists */ - if(oprop->value!=NULL) { - assert(prop->size>0); - if (NULL==(prop->value = H5MM_malloc (prop->size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - HDmemcpy(prop->value,oprop->value,prop->size); - } /* end if */ + /* Check arguments. */ + if(NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); - /* Set return value */ - ret_value=prop; + /* Create the new property list */ + if((ret_value = H5P_create_id(pclass)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list"); done: - /* Free any resources allocated */ - if(ret_value==NULL) { - if(prop!=NULL) { - if(prop->name!=NULL) - H5MM_xfree(prop->name); - if(prop->value!=NULL) - H5MM_xfree(prop->value); - H5FL_FREE(H5P_genprop_t,prop); - } /* end if */ - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_dup_prop() */ + FUNC_LEAVE_API(ret_value); +} /* H5Pcreate() */ /*-------------------------------------------------------------------------- NAME - H5P_create_prop + H5Pregister2 PURPOSE - Internal routine to create a new property + Routine to register a new property in a property list class. USAGE - H5P_genprop_t *H5P_create_prop(name,size,type,value,prp_create,prp_set, - prp_get,prp_delete,prp_close) + herr_t H5Pregister2(class, name, size, default, prp_create, prp_set, prp_get, prp_close) + hid_t class; IN: Property list class to close const char *name; IN: Name of property to register size_t size; IN: Size of property in bytes - H5P_prop_within_t type; IN: Type of object the property will be inserted into - void *value; IN: Pointer to buffer containing value for property + void *def_value; IN: Pointer to buffer containing default value + for property in newly created property lists H5P_prp_create_func_t prp_create; IN: Function pointer to property creation callback H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback @@ -1012,3758 +298,610 @@ done: H5P_prp_close_func_t prp_close; IN: Function pointer to property close callback RETURNS - Returns a pointer to the newly created property on success, - NULL on failure. + Returns non-negative on success, negative on failure. DESCRIPTION - Allocates memory and copies property information into a new property object. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5P_genprop_t * -H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type, - const void *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) -{ - H5P_genprop_t *prop=NULL; /* Pointer to new property copied */ - H5P_genprop_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_create_prop); - - assert(name); - assert((size>0 && value!=NULL) || (size==0)); - assert(type!=H5P_PROP_WITHIN_UNKNOWN); - - /* Allocate the new property */ - if (NULL==(prop = H5FL_MALLOC (H5P_genprop_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - - /* Set the property initial values */ - prop->name = H5MM_xstrdup(name); /* Duplicate name */ - prop->shared_name=0; - prop->size=size; - prop->type=type; - - /* Duplicate value, if it exists */ - if(value!=NULL) { - if (NULL==(prop->value = H5MM_malloc (prop->size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - HDmemcpy(prop->value,value,prop->size); - } /* end if */ - else - prop->value=NULL; - - /* Set the function pointers */ - prop->create=prp_create; - prop->set=prp_set; - prop->get=prp_get; - prop->del=prp_delete; - prop->copy=prp_copy; - /* Use custom comparison routine if available, otherwise default to memcmp() */ - if(prp_cmp!=NULL) - prop->cmp=prp_cmp; - else - prop->cmp=&memcmp; - prop->close=prp_close; - - /* Set return value */ - ret_value=prop; + Registers a new property with a property list class. The property will + exist in all property list objects of that class after this routine is + finished. The name of the property must not already exist. The default + property value must be provided and all new property lists created with this + property will have the property value set to the default provided. Any of + the callback routines may be set to NULL if they are not needed. -done: - /* Free any resources allocated */ - if(ret_value==NULL) { - if(prop!=NULL) { - if(prop->name!=NULL) - H5MM_xfree(prop->name); - if(prop->value!=NULL) - H5MM_xfree(prop->value); - H5FL_FREE(H5P_genprop_t,prop); - } /* end if */ - } /* end if */ + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'default' pointer for a + zero-sized property may be set to NULL. The property 'create' & 'close' + callbacks are called for zero-sized properties, but the 'set' and 'get' + callbacks are never called. - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_create_prop() */ + The 'create' callback is called when a new property list with this + property is being created. H5P_prp_create_func_t is defined as: + typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, + size_t size, void *initial_value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being created. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *initial_value; IN/OUT: The initial value for the property being created. + (The 'default' value passed to H5Pregister2) + The 'create' routine may modify the value to be set and those changes will + be stored as the initial value of the property. If the 'create' routine + returns a negative value, the new property value is not copied into the + property and the property list creation routine returns an error value. - -/*-------------------------------------------------------------------------- - NAME - H5P_add_prop - PURPOSE - Internal routine to insert a property into a property skip list - USAGE - herr_t H5P_add_prop(slist, prop) - H5SL_t *slist; IN/OUT: Pointer to skip list of properties - H5P_genprop_t *prop; IN: Pointer to property to insert - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Inserts a property into a skip list of properties. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_add_prop(H5SL_t *slist, H5P_genprop_t *prop) -{ - herr_t ret_value=SUCCEED; /* Return value */ + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. - FUNC_ENTER_NOAPI(H5P_add_prop,FAIL); + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'delete' callback is called when a property is deleted from a + property list. H5P_prp_del_func_t is defined as: + typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list the property is deleted from. + const char *name; IN: The name of the property being deleted. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value of the property being deleted. + The 'delete' routine may modify the value passed in, but the value is not + used by the library when the 'delete' routine returns. If the + 'delete' routine returns a negative value, the property list deletion + routine returns an error value but the property is still deleted. - assert(slist); - assert(prop); - assert(prop->type!=H5P_PROP_WITHIN_UNKNOWN); + The 'copy' callback is called when a property list with this + property is copied. H5P_prp_copy_func_t is defined as: + typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being copied. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being copied. + The 'copy' routine may modify the value to be copied and those changes will be + stored as the value of the property. If the 'copy' routine returns a + negative value, the new property value is not copied into the property and + the property list copy routine returns an error value. - /* Insert property into skip list */ - if(H5SL_insert(slist,prop,prop->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into skip list"); + The 'compare' callback is called when a property list with this + property is compared to another property list. H5P_prp_compare_func_t is + defined as: + typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, + size_t size); + where the parameters to the callback function are: + const void *value1; IN: The value of the first property being compared. + const void *value2; IN: The value of the second property being compared. + size_t size; IN: The size of the property value + The 'compare' routine may not modify the values to be compared. The + 'compare' routine should return a positive value if VALUE1 is greater than + VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 + and VALUE2 are equal. -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_add_prop() */ + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. - -/*-------------------------------------------------------------------------- - NAME - H5P_find_prop_plist - PURPOSE - Internal routine to check for a property in a property list's skip list - USAGE - H5P_genprop_t *H5P_find_prop(plist, name) - H5P_genplist_t *plist; IN: Pointer to property list to check - const char *name; IN: Name of property to check for - RETURNS - Returns pointer to property on success, NULL on failure. - DESCRIPTION - Checks for a property in a property list's skip list of properties. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5P_genprop_t * -H5P_find_prop_plist(H5P_genplist_t *plist, const char *name) -{ - H5P_genprop_t *ret_value; /* Property pointer return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_plist); - - assert(plist); - assert(name); - - /* Check if the property has been deleted from list */ - if(H5SL_search(plist->del,name)!=NULL) { - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list"); - } /* end if */ - else { - /* Get the property data from the skip list */ - if((ret_value=H5SL_search(plist->props,name))==NULL) { - H5P_genclass_t *tclass; /* Temporary class pointer */ - - /* Couldn't find property in list itself, start searching through class info */ - tclass=plist->pclass; - while(tclass!=NULL) { - /* Find the property in the class */ - if((ret_value=H5SL_search(tclass->props,name))!=NULL) - /* Got pointer to property - leave now */ - break; - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* Check if we haven't found the property */ - if(ret_value==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list"); - } /* end else */ - } /* end else */ + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_find_prop_plist() */ + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK - -/*-------------------------------------------------------------------------- - NAME - H5P_find_prop_pclass - PURPOSE - Internal routine to check for a property in a class skip list - USAGE - H5P_genprop_t *H5P_find_prop_class(pclass, name) - H5P_genclass *pclass; IN: Pointer generic property class to check - const char *name; IN: Name of property to check for - RETURNS - Returns pointer to property on success, NULL on failure. - DESCRIPTION - Checks for a property in a class's skip list of properties. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static H5P_genprop_t * -H5P_find_prop_pclass(H5P_genclass_t *pclass, const char *name) +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) { - H5P_genprop_t *ret_value; /* Property pointer return value */ + H5P_genclass_t *pclass; /* Property list class to modify */ + herr_t ret_value; /* return value */ - FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_pclass); + FUNC_ENTER_API(H5Pregister2, FAIL); + H5TRACE11("e","iszxxxxxxxx",cls_id,name,size,def_value,prp_create,prp_set, + prp_get,prp_delete,prp_copy,prp_cmp,prp_close); - assert(pclass); - assert(name); + /* Check arguments. */ + if(NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); + if(size>0 && def_value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); - /* Get the property from the skip list */ - if((ret_value=H5SL_search(pclass->props,name))==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list"); + /* Create the new property list class */ + if((ret_value = H5P_register(pclass,name,size,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class"); done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_find_prop_pclass() */ + FUNC_LEAVE_API(ret_value); +} /* H5Pregister2() */ /*-------------------------------------------------------------------------- NAME - H5P_free_prop + H5Pinsert PURPOSE - Internal routine to destroy a property node + Routine to insert a new property in a property list. USAGE - herr_t H5P_free_prop(prop) - H5P_genprop_t *prop; IN: Pointer to property to destroy + herr_t H5Pinsert(plist, name, size, value, prp_set, prp_get, prp_close) + hid_t plist; IN: Property list to add property to + const char *name; IN: Name of property to add + size_t size; IN: Size of property in bytes + void *value; IN: Pointer to the value for the property + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback + H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback + H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback RETURNS Returns non-negative on success, negative on failure. DESCRIPTION - Releases all the memory for a property list. Does _not_ call the - properties 'close' callback, that should already have been done. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_free_prop(H5P_genprop_t *prop) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop); + Inserts a temporary property into a property list. The property will + exist only in this property list object. The name of the property must not + already exist. The value must be provided unless the property is zero- + sized. Any of the callback routines may be set to NULL if they are not + needed. - assert(prop); + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'value' pointer for a + zero-sized property may be set to NULL. The property 'close' callback is + called for zero-sized properties, but the 'set' and 'get' callbacks are + never called. - /* Release the property value if it exists */ - if(prop->value) - H5MM_xfree(prop->value); + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. - /* Only free the name if we own it */ - if(prop->shared_name==0) - H5MM_xfree(prop->name); + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. - H5FL_FREE(H5P_genprop_t,prop); + The 'delete' callback is called when a property is deleted from a + property list. H5P_prp_del_func_t is defined as: + typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list the property is deleted from. + const char *name; IN: The name of the property being deleted. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value of the property being deleted. + The 'delete' routine may modify the value passed in, but the value is not + used by the library when the 'delete' routine returns. If the + 'delete' routine returns a negative value, the property list deletion + routine returns an error value but the property is still deleted. - FUNC_LEAVE_NOAPI(SUCCEED); -} /* H5P_free_prop() */ + The 'copy' callback is called when a property list with this + property is copied. H5P_prp_copy_func_t is defined as: + typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being copied. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being copied. + The 'copy' routine may modify the value to be copied and those changes will be + stored as the value of the property. If the 'copy' routine returns a + negative value, the new property value is not copied into the property and + the property list copy routine returns an error value. - -/*-------------------------------------------------------------------------- - NAME - H5P_free_prop_cb - PURPOSE - Internal routine to properties from a property skip list - USAGE - herr_t H5P_free_prop_cb(item, key, op_data) - void *item; IN/OUT: Pointer to property - void *key; IN/OUT: Pointer to property key - void *_make_cb; IN: Whether to make property callbacks or not - RETURNS - Returns zero on success, negative on failure. - DESCRIPTION - Calls the property 'close' callback for a property & frees property - info. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_free_prop_cb(void *item, void UNUSED *key, void *op_data) -{ - H5P_genprop_t *tprop=(H5P_genprop_t *)item; /* Temporary pointer to property */ - unsigned make_cb=*(unsigned *)op_data; /* Whether to make property 'close' callback */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop_cb); - - assert(tprop); - - /* Call the close callback and ignore the return value, there's nothing we can do about it */ - if(make_cb && tprop->close!=NULL) - (tprop->close)(tprop->name,tprop->size,tprop->value); - - /* Free the property, ignoring return value, nothing we can do */ - H5P_free_prop(tprop); - - FUNC_LEAVE_NOAPI(0); -} /* H5P_free_prop_cb() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_free_del_name_cb - PURPOSE - Internal routine to free 'deleted' property name - USAGE - herr_t H5P_free_del_name_cb(item, key, op_data) - void *item; IN/OUT: Pointer to deleted name - void *key; IN/OUT: Pointer to key - void *op_data; IN: Operator callback data (unused) - RETURNS - Returns zero on success, negative on failure. - DESCRIPTION - Frees the deleted property name - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_free_del_name_cb(void *item, void UNUSED *key, void UNUSED *op_data) -{ - char *del_name=(char *)item; /* Temporary pointer to deleted name */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_del_name_cb); - - assert(del_name); - - /* Free the name */ - H5MM_xfree(del_name); - - FUNC_LEAVE_NOAPI(0); -} /* H5P_free_del_name_cb() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_access_class - PURPOSE - Internal routine to increment or decrement list & class dependancies on a - property list class - USAGE - herr_t H5P_access_class(pclass,mod) - H5P_genclass_t *pclass; IN: Pointer to class to modify - H5P_class_mod_t mod; IN: Type of modification to class - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Increment/Decrement the class or list dependancies for a given class. - This routine is the final arbiter on decisions about actually releasing a - class in memory, such action is only taken when the reference counts for - both dependent classes & lists reach zero. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_access_class); - - assert(pclass); - assert(mod>H5P_MOD_ERR && modclasses++; - break; - - case H5P_MOD_DEC_CLS: /* Decrement the dependant class count*/ - pclass->classes--; - break; - - case H5P_MOD_INC_LST: /* Increment the dependant list count*/ - pclass->plists++; - break; - - case H5P_MOD_DEC_LST: /* Decrement the dependant list count*/ - pclass->plists--; - break; - - case H5P_MOD_INC_REF: /* Increment the ID reference count*/ - /* Reset the deleted flag if incrementing the reference count */ - if(pclass->deleted) - pclass->deleted=0; - pclass->ref_count++; - break; - - case H5P_MOD_DEC_REF: /* Decrement the ID reference count*/ - pclass->ref_count--; - - /* Mark the class object as deleted if reference count drops to zero */ - if(pclass->ref_count==0) - pclass->deleted=1; - break; - - case H5P_MOD_ERR: - case H5P_MOD_MAX: - assert(0 && "Invalid H5P class modification"); - } /* end switch */ - - /* Check if we can release the class information now */ - if(pclass->deleted && pclass->plists==0 && pclass->classes==0 ) { - H5P_genclass_t *par_class=pclass->parent; /* Pointer to class's parent */ - - assert(pclass->name); - H5MM_xfree(pclass->name); - - /* Free the class properties without making callbacks */ - if(pclass->props) { - unsigned make_cb=0; - - H5SL_destroy(pclass->props,H5P_free_prop_cb,&make_cb); - } /* end if */ - - H5FL_FREE(H5P_genclass_t,pclass); - - /* Reduce the number of dependent classes on parent class also */ - if(par_class!=NULL) - H5P_access_class(par_class, H5P_MOD_DEC_CLS); - } /* end if */ - - FUNC_LEAVE_NOAPI(SUCCEED); -} /* H5P_access_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_check_class - PURPOSE - Internal callback routine to check for duplicated names in parent class. - USAGE - int H5P_check_class(obj, id, key) - H5P_genclass_t *obj; IN: Pointer to class - hid_t id; IN: ID of object being looked at - const void *key; IN: Pointer to information used to compare - classes. - RETURNS - Returns >0 on match, 0 on no match and <0 on failure. - DESCRIPTION - Checks whether a property list class has the same parent and name as a - new class being created. This is a callback routine for H5I_search() - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static int -H5P_check_class(void *_obj, hid_t UNUSED id, void *_key) -{ - H5P_genclass_t *obj=(H5P_genclass_t *)_obj; /* Pointer to the class for this ID */ - const H5P_check_class_t *key=(const H5P_check_class_t *)_key; /* Pointer to key information for comparison */ - int ret_value=0; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_check_class); - - assert(obj); - assert(H5I_GENPROP_CLS==H5I_get_type(id)); - assert(key); - - /* Check if the class object has the same parent as the new class */ - if(obj->parent==key->parent) { - /* Check if they have the same name */ - if(HDstrcmp(obj->name,key->name)==0) - ret_value=1; /* Indicate a match */ - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5P_check_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_create_class - PURPOSE - Internal routine to create a new property list class. - USAGE - H5P_genclass_t H5P_create_class(par_class, name, internal, - cls_create, create_data, cls_close, close_data) - H5P_genclass_t *par_class; IN: Pointer to parent class - const char *name; IN: Name of class we are creating - unsigned internal; IN: Whether this is an internal class or not - H5P_cls_create_func_t; IN: The callback function to call when each - property list in this class is created. - void *create_data; IN: Pointer to user data to pass along to class - creation callback. - H5P_cls_copy_func_t; IN: The callback function to call when each - property list in this class is copied. - void *copy_data; IN: Pointer to user data to pass along to class - copy callback. - H5P_cls_close_func_t; IN: The callback function to call when each - property list in this class is closed. - void *close_data; IN: Pointer to user data to pass along to class - close callback. - RETURNS - Returns a pointer to the newly created property list class on success, - NULL on failure. - DESCRIPTION - Allocates memory and attaches a class to the property list class hierarchy. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -H5P_genclass_t * -H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal, - 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) -{ - H5P_genclass_t *pclass=NULL; /* Property list class created */ - H5P_genclass_t *ret_value; /* return value */ - - FUNC_ENTER_NOAPI(H5P_create_class, NULL) - - assert(name); - /* Allow internal classes to break some rules */ - /* (This allows the root of the tree to be created with this routine -QAK) */ - if(!internal) { - assert(par_class); - } - - /* Allocate room for the class */ - if (NULL==(pclass = H5FL_CALLOC(H5P_genclass_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); - - /* Set class state */ - pclass->parent = par_class; - pclass->name = H5MM_xstrdup(name); - pclass->nprops = 0; /* Classes are created without properties initially */ - pclass->plists = 0; /* No properties lists of this class yet */ - pclass->classes = 0; /* No classes derived from this class yet */ - pclass->ref_count = 1; /* This is the first reference to the new class */ - pclass->internal = internal; - pclass->deleted = 0; /* Not deleted yet... :-) */ - pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */ - - /* Create the skip list for properties */ - if((pclass->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for properties"); - - /* Set callback functions and pass-along data */ - pclass->create_func = cls_create; - pclass->create_data = create_data; - pclass->copy_func = cls_copy; - pclass->copy_data = copy_data; - pclass->close_func = cls_close; - pclass->close_data = close_data; - - /* Increment parent class's derived class value */ - if(par_class!=NULL) { - if(H5P_access_class(par_class,H5P_MOD_INC_CLS)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment parent class ref count"); - } /* end if */ - - /* Set return value */ - ret_value=pclass; - -done: - /* Free any resources allocated */ - if(ret_value==NULL) - if(pclass!=NULL) - H5FL_FREE(H5P_genclass_t,pclass); - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5P_create_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pcreate_class - PURPOSE - Create a new property list class. - USAGE - hid_t H5Pcreate_class(parent, name, cls_create, create_data, - cls_close, close_data) - hid_t parent; IN: Property list class ID of parent class - const char *name; IN: Name of class we are creating - H5P_cls_create_func_t cls_create; IN: The callback function to call - when each property list in this class is - created. - void *create_data; IN: Pointer to user data to pass along to class - creation callback. - H5P_cls_copy_func_t cls_copy; IN: The callback function to call - when each property list in this class is - copied. - void *copy_data; IN: Pointer to user data to pass along to class - copy callback. - H5P_cls_close_func_t cls_close; IN: The callback function to call - when each property list in this class is - closed. - void *close_data; IN: Pointer to user data to pass along to class - close callback. - RETURNS - Returns a valid property list class ID on success, NULL on failure. - DESCRIPTION - Allocates memory and attaches a class to the property list class hierarchy. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -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 - ) -{ - H5P_genclass_t *par_class = NULL; /* Pointer to the parent class */ - H5P_genclass_t *pclass = NULL; /* Property list class created */ - hid_t ret_value; /* Return value */ - - FUNC_ENTER_API(H5Pcreate_class, FAIL); - H5TRACE8("i", "i*sx*xx*xx*x", parent, name, cls_create, create_data, cls_copy, - copy_data, cls_close, close_data); - - /* Check arguments. */ - if (H5P_DEFAULT!=parent && (H5I_GENPROP_CLS!=H5I_get_type(parent))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); - if ((create_data!=NULL && cls_create==NULL) - || (copy_data!=NULL && cls_copy==NULL) - || (close_data!=NULL && cls_close==NULL)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data specified, but no callback provided"); - - /* Get the pointer to the parent class */ - if(parent==H5P_DEFAULT) - par_class=NULL; - else if (NULL == (par_class = H5I_object(parent))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't retrieve parent class"); - - /* Create the new property list class */ - if (NULL==(pclass=H5P_create_class(par_class, name, 0, cls_create, create_data, cls_copy, copy_data, cls_close, close_data))) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class"); - - /* Get an atom for the class */ - if ((ret_value = H5I_register(H5I_GENPROP_CLS, pclass))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); - -done: - if (ret_value<0 && pclass) - H5P_close_class(pclass); - - FUNC_LEAVE_API(ret_value); -} /* H5Pcreate_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_create - PURPOSE - Internal routine to create a new property list of a property list class. - USAGE - H5P_genplist_t *H5P_create(class) - H5P_genclass_t *class; IN: Property list class create list from - RETURNS - Returns a pointer to the newly created property list on success, - NULL on failure. - DESCRIPTION - Creates a property list of a given class. If a 'create' callback - exists for the property list class, it is called before the - property list is passed back to the user. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - If this routine is called from a library routine other than - H5P_c, the calling routine is responsible for getting an ID for - the property list and calling the class 'create' callback (if one exists) - and also setting the "class_init" flag. - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5P_genplist_t * -H5P_create(H5P_genclass_t *pclass) -{ - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genplist_t *plist=NULL; /* New property list created */ - H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */ - H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */ - H5P_genplist_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_create); - - assert(pclass); - - /* - * Create new property list object - */ - - /* Allocate room for the property list */ - if (NULL==(plist = H5FL_CALLOC(H5P_genplist_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); - - /* Set class state */ - plist->pclass = pclass; - plist->nprops = 0; /* Initially the plist has the same number of properties as the class */ - plist->class_init = 0; /* Initially, wait until the class callback finishes to set */ - - /* Create the skip list for changed properties */ - if((plist->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties"); - - /* Create the skip list for deleted properties */ - if((plist->del = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties"); - - /* Create the skip list to hold names of properties already seen - * (This prevents a property in the class hierarchy from having it's - * 'create' callback called, if a property in the class hierarchy has - * already been seen) - */ - if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties"); - - /* - * Check if we should copy class properties (up through list of parent classes also), - * initialize each with default value & make property 'create' callback. - */ - tclass=pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - H5SL_node_t *curr_node; /* Current node in skip list */ - - /* Walk through the properties in the old class */ - curr_node=H5SL_first(tclass->props); - while(curr_node!=NULL) { - /* Get pointer to property from node */ - tmp=H5SL_item(curr_node); - - /* Only "create" properties we haven't seen before */ - if(H5SL_search(seen,tmp->name)==NULL) { - /* Call property creation callback, if it exists */ - if(tmp->create) { - /* Call the callback & insert changed value into skip list (if necessary) */ - if(H5P_do_prop_cb1(plist->props,tmp,tmp->create)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property"); - } /* end if */ - - /* Add property name to "seen" list */ - if(H5SL_insert(seen,tmp->name,tmp->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen skip list"); - - /* Increment the number of properties in list */ - plist->nprops++; - } /* end if */ - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* Increment the number of property lists derived from class */ - if(H5P_access_class(plist->pclass,H5P_MOD_INC_LST)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment class ref count"); - - /* Set return value */ - ret_value=plist; - -done: - /* Release the skip list of 'seen' properties */ - if(seen!=NULL) - H5SL_close(seen); - - /* Release resources allocated on failure */ - if(ret_value==NULL) { - if(plist!=NULL) { - /* Close & free any changed properties */ - if(plist->props) { - unsigned make_cb=1; - - H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb); - } /* end if */ - - /* Close the deleted property skip list */ - if(plist->del) - H5SL_close(plist->del); - - /* Release the property list itself */ - H5FL_FREE(H5P_genplist_t,plist); - } /* end if */ - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_create() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_create_id - PURPOSE - Internal routine to create a new property list of a property list class. - USAGE - hid_t H5P_create_id(pclass) - H5P_genclass_t *pclass; IN: Property list class create list from - RETURNS - Returns a valid property list ID on success, FAIL on failure. - DESCRIPTION - Creates a property list of a given class. If a 'create' callback - exists for the property list class, it is called before the - property list is passed back to the user. If 'create' callbacks exist for - any individual properties in the property list, they are called before the - class 'create' callback. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -hid_t -H5P_create_id(H5P_genclass_t *pclass) -{ - H5P_genplist_t *plist=NULL; /* Property list created */ - hid_t plist_id=FAIL; /* Property list ID */ - hid_t ret_value; /* return value */ - - FUNC_ENTER_NOAPI(H5P_create_id, FAIL); - - assert(pclass); - - /* Create the new property list */ - if ((plist=H5P_create(pclass))==NULL) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list"); - - /* Get an atom for the property list */ - if ((plist_id = H5I_register(H5I_GENPROP_LST, plist))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list"); - - /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */ - plist->plist_id=plist_id; - - /* Call the class callback (if it exists) now that we have the property list ID */ - if(plist->pclass->create_func!=NULL) { - if((plist->pclass->create_func)(plist_id,plist->pclass->create_data)<0) { - /* Delete ID, ignore return value */ - H5I_remove(plist_id); - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); - } /* end if */ - } /* end if */ - - /* Set the class initialization flag */ - plist->class_init=1; - - /* Set the return value */ - ret_value=plist_id; - -done: - if (ret_value<0 && plist) - H5P_close(plist); - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_create_id() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pcreate - PURPOSE - Routine to create a new property list of a property list class. - USAGE - hid_t H5Pcreate(cls_id) - hid_t cls_id; IN: Property list class create list from - RETURNS - Returns a valid property list ID on success, FAIL on failure. - DESCRIPTION - Creates a property list of a given class. If a 'create' callback - exists for the property list class, it is called before the - property list is passed back to the user. If 'create' callbacks exist for - any individual properties in the property list, they are called before the - class 'create' callback. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -hid_t -H5Pcreate(hid_t cls_id) -{ - H5P_genclass_t *pclass; /* Property list class to modify */ - hid_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pcreate, FAIL); - H5TRACE1("i", "i", cls_id); - - /* Check arguments. */ - if (NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); - - /* Create the new property list */ - if((ret_value=H5P_create_id(pclass))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list"); - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pcreate() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_register - PURPOSE - Internal routine to register a new property in a property list class. - USAGE - herr_t H5P_register(class, name, size, default, prp_create, prp_set, prp_get, prp_close) - H5P_genclass_t *class; IN: Property list class to close - const char *name; IN: Name of property to register - size_t size; IN: Size of property in bytes - void *def_value; IN: Pointer to buffer containing default value - for property in newly created property lists - H5P_prp_create_func_t prp_create; IN: Function pointer to property - creation callback - H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback - H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback - H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback - H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback - H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback - H5P_prp_close_func_t prp_close; IN: Function pointer to property close - callback - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Registers a new property with a property list class. The property will - exist in all property list objects of that class after this routine is - finished. The name of the property must not already exist. The default - property value must be provided and all new property lists created with this - property will have the property value set to the default provided. Any of - the callback routines may be set to NULL if they are not needed. - - Zero-sized properties are allowed and do not store any data in the - property list. These may be used as flags to indicate the presence or - absence of a particular piece of information. The 'default' pointer for a - zero-sized property may be set to NULL. The property 'create' & 'close' - callbacks are called for zero-sized properties, but the 'set' and 'get' - callbacks are never called. - - The 'create' callback is called when a new property list with this - property is being created. H5P_prp_create_func_t is defined as: - typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, - size_t size, void *initial_value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being created. - const char *name; IN: The name of the property being modified. - size_t size; IN: The size of the property value - void *initial_value; IN/OUT: The initial value for the property being created. - (The 'default' value passed to H5Pregister) - The 'create' routine may modify the value to be set and those changes will - be stored as the initial value of the property. If the 'create' routine - returns a negative value, the new property value is not copied into the - property and the property list creation routine returns an error value. - - The 'set' callback is called before a new value is copied into the - property. H5P_prp_set_func_t is defined as: - typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being modified. - const char *name; IN: The name of the property being modified. - size_t size; IN: The size of the property value - void *new_value; IN/OUT: The value being set for the property. - The 'set' routine may modify the value to be set and those changes will be - stored as the value of the property. If the 'set' routine returns a - negative value, the new property value is not copied into the property and - the property list set routine returns an error value. - - The 'get' callback is called before a value is retrieved from the - property. H5P_prp_get_func_t is defined as: - typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being queried. - const char *name; IN: The name of the property being queried. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value being retrieved for the property. - The 'get' routine may modify the value to be retrieved and those changes - will be returned to the calling function. If the 'get' routine returns a - negative value, the property value is returned and the property list get - routine returns an error value. - - The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list the property is deleted from. - const char *name; IN: The name of the property being deleted. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value of the property being deleted. - The 'delete' routine may modify the value passed in, but the value is not - used by the library when the 'delete' routine returns. If the - 'delete' routine returns a negative value, the property list deletion - routine returns an error value but the property is still deleted. - - The 'copy' callback is called when a property list with this - property is copied. H5P_prp_copy_func_t is defined as: - typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being copied. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being copied. - The 'copy' routine may modify the value to be copied and those changes will be - stored as the value of the property. If the 'copy' routine returns a - negative value, the new property value is not copied into the property and - the property list copy routine returns an error value. - - The 'compare' callback is called when a property list with this - property is compared to another property list. H5P_prp_compare_func_t is - defined as: - typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, - size_t size); - where the parameters to the callback function are: - const void *value1; IN: The value of the first property being compared. - const void *value2; IN: The value of the second property being compared. - size_t size; IN: The size of the property value - The 'compare' routine may not modify the values to be compared. The - 'compare' routine should return a positive value if VALUE1 is greater than - VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 - and VALUE2 are equal. - - The 'close' callback is called when a property list with this - property is being destroyed. H5P_prp_close_func_t is defined as: - typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being closed. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being closed. - The 'close' routine may modify the value passed in, but the value is not - used by the library when the 'close' routine returns. If the - 'close' routine returns a negative value, the property list close - routine returns an error value but the property list is still closed. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - The 'set' callback function may be useful to range check the value being - set for the property or may perform some tranformation/translation of the - value set. The 'get' callback would then [probably] reverse the - transformation, etc. A single 'get' or 'set' callback could handle - multiple properties by performing different actions based on the property - name or other properties in the property list. - - I would like to say "the property list is not closed" when a 'close' - routine fails, but I don't think that's possible due to other properties in - the list being successfully closed & removed from the property list. I - suppose that it would be possible to just remove the properties which have - successful 'close' callbacks, but I'm not happy with the ramifications - of a mangled, un-closable property list hanging around... Any comments? -QAK - - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_register(H5P_genclass_t *pclass, const char *name, size_t size, - const 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) -{ - H5P_genclass_t *new_class; /* New class pointer */ - H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */ - H5P_genprop_t *pcopy; /* Property copy */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_register, FAIL); - - assert(pclass); - assert(name); - assert((size>0 && def_value!=NULL) || (size==0)); - - /* Check for duplicate named properties */ - if(H5SL_search(pclass->props,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); - - /* Check if class needs to be split because property lists or classes have - * been created since the last modification was made to the class. - */ - if(pclass->plists>0 || pclass->classes>0) { - if((new_class=H5P_create_class(pclass->parent,pclass->name, - pclass->internal,pclass->create_func,pclass->create_data, - pclass->copy_func,pclass->copy_data, - pclass->close_func,pclass->close_data))==NULL) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy class"); - - /* Walk through the skip list of the old class and copy properties */ - if(pclass->nprops>0) { - H5SL_node_t *curr_node; /* Current node in skip list */ - - /* Walk through the properties in the old class */ - curr_node=H5SL_first(pclass->props); - while(curr_node!=NULL) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); - - /* Insert the initialized property into the property list */ - if(H5P_add_prop(new_class->props,pcopy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); - - /* Increment property count for class */ - new_class->nprops++; - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Use the new class instead of the old one */ - pclass=new_class; - } /* end if */ - - /* Create property object from parameters */ - if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_CLASS,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); - - /* Insert property into property list class */ - if(H5P_add_prop(pclass->props,new_prop)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); - - /* Increment property count for class */ - pclass->nprops++; - - /* Update the revision for the class */ - pclass->revision = H5P_GET_NEXT_REV; - -done: - if(ret_value==FAIL) { - if(new_prop!=NULL) { - if(new_prop->name!=NULL) - H5MM_xfree(new_prop->name); - if(new_prop->value!=NULL) - H5MM_xfree(new_prop->value); - H5FL_FREE(H5P_genprop_t,new_prop); - } /* end if */ - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_register() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pregister - PURPOSE - Routine to register a new property in a property list class. - USAGE - herr_t H5Pregister(class, name, size, default, prp_create, prp_set, prp_get, prp_close) - hid_t class; IN: Property list class to close - const char *name; IN: Name of property to register - size_t size; IN: Size of property in bytes - void *def_value; IN: Pointer to buffer containing default value - for property in newly created property lists - H5P_prp_create_func_t prp_create; IN: Function pointer to property - creation callback - H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback - H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback - H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback - H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback - H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback - H5P_prp_close_func_t prp_close; IN: Function pointer to property close - callback - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Registers a new property with a property list class. The property will - exist in all property list objects of that class after this routine is - finished. The name of the property must not already exist. The default - property value must be provided and all new property lists created with this - property will have the property value set to the default provided. Any of - the callback routines may be set to NULL if they are not needed. - - Zero-sized properties are allowed and do not store any data in the - property list. These may be used as flags to indicate the presence or - absence of a particular piece of information. The 'default' pointer for a - zero-sized property may be set to NULL. The property 'create' & 'close' - callbacks are called for zero-sized properties, but the 'set' and 'get' - callbacks are never called. - - The 'create' callback is called when a new property list with this - property is being created. H5P_prp_create_func_t is defined as: - typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, - size_t size, void *initial_value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being created. - const char *name; IN: The name of the property being modified. - size_t size; IN: The size of the property value - void *initial_value; IN/OUT: The initial value for the property being created. - (The 'default' value passed to H5Pregister) - The 'create' routine may modify the value to be set and those changes will - be stored as the initial value of the property. If the 'create' routine - returns a negative value, the new property value is not copied into the - property and the property list creation routine returns an error value. - - The 'set' callback is called before a new value is copied into the - property. H5P_prp_set_func_t is defined as: - typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being modified. - const char *name; IN: The name of the property being modified. - size_t size; IN: The size of the property value - void *new_value; IN/OUT: The value being set for the property. - The 'set' routine may modify the value to be set and those changes will be - stored as the value of the property. If the 'set' routine returns a - negative value, the new property value is not copied into the property and - the property list set routine returns an error value. - - The 'get' callback is called before a value is retrieved from the - property. H5P_prp_get_func_t is defined as: - typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being queried. - const char *name; IN: The name of the property being queried. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value being retrieved for the property. - The 'get' routine may modify the value to be retrieved and those changes - will be returned to the calling function. If the 'get' routine returns a - negative value, the property value is returned and the property list get - routine returns an error value. - - The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list the property is deleted from. - const char *name; IN: The name of the property being deleted. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value of the property being deleted. - The 'delete' routine may modify the value passed in, but the value is not - used by the library when the 'delete' routine returns. If the - 'delete' routine returns a negative value, the property list deletion - routine returns an error value but the property is still deleted. - - The 'copy' callback is called when a property list with this - property is copied. H5P_prp_copy_func_t is defined as: - typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being copied. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being copied. - The 'copy' routine may modify the value to be copied and those changes will be - stored as the value of the property. If the 'copy' routine returns a - negative value, the new property value is not copied into the property and - the property list copy routine returns an error value. - - The 'compare' callback is called when a property list with this - property is compared to another property list. H5P_prp_compare_func_t is - defined as: - typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, - size_t size); - where the parameters to the callback function are: - const void *value1; IN: The value of the first property being compared. - const void *value2; IN: The value of the second property being compared. - size_t size; IN: The size of the property value - The 'compare' routine may not modify the values to be compared. The - 'compare' routine should return a positive value if VALUE1 is greater than - VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 - and VALUE2 are equal. - - The 'close' callback is called when a property list with this - property is being destroyed. H5P_prp_close_func_t is defined as: - typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being closed. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being closed. - The 'close' routine may modify the value passed in, but the value is not - used by the library when the 'close' routine returns. If the - 'close' routine returns a negative value, the property list close - routine returns an error value but the property list is still closed. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - The 'set' callback function may be useful to range check the value being - set for the property or may perform some tranformation/translation of the - value set. The 'get' callback would then [probably] reverse the - transformation, etc. A single 'get' or 'set' callback could handle - multiple properties by performing different actions based on the property - name or other properties in the property list. - - I would like to say "the property list is not closed" when a 'close' - routine fails, but I don't think that's possible due to other properties in - the list being successfully closed & removed from the property list. I - suppose that it would be possible to just remove the properties which have - successful 'close' callbacks, but I'm not happy with the ramifications - of a mangled, un-closable property list hanging around... Any comments? -QAK - - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -#ifdef H5_WANT_H5_V1_6_COMPAT -herr_t -H5Pregister(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_close_func_t prp_close) -#else /* H5_WANT_H5_V1_6_COMPAT */ -herr_t -H5Pregister(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) -#endif /* H5_WANT_H5_V1_6_COMPAT */ -{ - H5P_genclass_t *pclass; /* Property list class to modify */ - herr_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pregister, FAIL); -#ifdef H5_WANT_H5_V1_6_COMPAT - H5TRACE10("e","iszxxxxxxx",cls_id,name,size,def_value,prp_create,prp_set, - prp_get,prp_delete,prp_copy,prp_close); -#else /* H5_WANT_H5_V1_6_COMPAT */ - H5TRACE11("e","iszxxxxxxxx",cls_id,name,size,def_value,prp_create,prp_set, - prp_get,prp_delete,prp_copy,prp_cmp,prp_close); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - - /* Check arguments. */ - if (NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); - if (size>0 && def_value==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); - -#ifdef H5_WANT_H5_V1_6_COMPAT - /* Create the new property list class */ - if ((ret_value=H5P_register(pclass,name,size,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,NULL,prp_close))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class"); -#else /* H5_WANT_H5_V1_6_COMPAT */ - /* Create the new property list class */ - if ((ret_value=H5P_register(pclass,name,size,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class"); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pregister() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_insert - PURPOSE - Internal routine to insert a new property in a property list. - USAGE - herr_t H5P_insert(plist, name, size, value, prp_set, prp_get, prp_close) - H5P_genplist_t *plist; IN: Property list to add property to - const char *name; IN: Name of property to add - size_t size; IN: Size of property in bytes - void *value; IN: Pointer to the value for the property - H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback - H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback - H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback - H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback - H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback - H5P_prp_close_func_t prp_close; IN: Function pointer to property close - callback - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Inserts a temporary property into a property list. The property will - exist only in this property list object. The name of the property must not - already exist. The value must be provided unless the property is zero- - sized. Any of the callback routines may be set to NULL if they are not - needed. - - Zero-sized properties are allowed and do not store any data in the - property list. These may be used as flags to indicate the presence or - absence of a particular piece of information. The 'value' pointer for a - zero-sized property may be set to NULL. The property 'close' callback is - called for zero-sized properties, but the 'set' and 'get' callbacks are - never called. - - The 'set' callback is called before a new value is copied into the - property. H5P_prp_set_func_t is defined as: - typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being modified. - const char *name; IN: The name of the property being modified. - size_t size; IN: The size of the property value - void *new_value; IN/OUT: The value being set for the property. - The 'set' routine may modify the value to be set and those changes will be - stored as the value of the property. If the 'set' routine returns a - negative value, the new property value is not copied into the property and - the property list set routine returns an error value. - - The 'get' callback is called before a value is retrieved from the - property. H5P_prp_get_func_t is defined as: - typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being queried. - const char *name; IN: The name of the property being queried. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value being retrieved for the property. - The 'get' routine may modify the value to be retrieved and those changes - will be returned to the calling function. If the 'get' routine returns a - negative value, the property value is returned and the property list get - routine returns an error value. - - The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list the property is deleted from. - const char *name; IN: The name of the property being deleted. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value of the property being deleted. - The 'delete' routine may modify the value passed in, but the value is not - used by the library when the 'delete' routine returns. If the - 'delete' routine returns a negative value, the property list deletion - routine returns an error value but the property is still deleted. - - The 'copy' callback is called when a property list with this - property is copied. H5P_prp_copy_func_t is defined as: - typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being copied. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being copied. - The 'copy' routine may modify the value to be copied and those changes will be - stored as the value of the property. If the 'copy' routine returns a - negative value, the new property value is not copied into the property and - the property list copy routine returns an error value. - - The 'compare' callback is called when a property list with this - property is compared to another property list. H5P_prp_compare_func_t is - defined as: - typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, - size_t size); - where the parameters to the callback function are: - const void *value1; IN: The value of the first property being compared. - const void *value2; IN: The value of the second property being compared. - size_t size; IN: The size of the property value - The 'compare' routine may not modify the values to be compared. The - 'compare' routine should return a positive value if VALUE1 is greater than - VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 - and VALUE2 are equal. - - The 'close' callback is called when a property list with this - property is being destroyed. H5P_prp_close_func_t is defined as: - typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being closed. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being closed. - The 'close' routine may modify the value passed in, but the value is not - used by the library when the 'close' routine returns. If the - 'close' routine returns a negative value, the property list close - routine returns an error value but the property list is still closed. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - The 'set' callback function may be useful to range check the value being - set for the property or may perform some tranformation/translation of the - value set. The 'get' callback would then [probably] reverse the - transformation, etc. A single 'get' or 'set' callback could handle - multiple properties by performing different actions based on the property - name or other properties in the property list. - - There is no 'create' callback routine for temporary property list - objects, the initial value is assumed to have any necessary setup already - performed on it. - - I would like to say "the property list is not closed" when a 'close' - routine fails, but I don't think that's possible due to other properties in - the list being successfully closed & removed from the property list. I - suppose that it would be possible to just remove the properties which have - successful 'close' callbacks, but I'm not happy with the ramifications - of a mangled, un-closable property list hanging around... Any comments? -QAK - - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_insert(H5P_genplist_t *plist, 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) -{ - H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_insert); - - assert(plist); - assert(name); - assert((size>0 && value!=NULL) || (size==0)); - - /* Check for duplicate named properties */ - if(H5SL_search(plist->props,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); - - /* Check if the property has been deleted */ - if(H5SL_search(plist->del,name)!=NULL) { - /* Remove the property name from the deleted property skip list */ - if(H5SL_remove(plist->del,name)==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from deleted skip list"); - - /* Fall through to add property to list */ - } /* end if */ - else { - H5P_genclass_t *tclass; /* Temporary class pointer */ - - /* Check if the property is already in the class hierarchy */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Find the property in the class */ - if(H5SL_search(tclass->props,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* Fall through to add property to list */ - } /* end else */ - - /* Ok to add to property list */ - - /* Create property object from parameters */ - if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_LIST,value,NULL,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); - - /* Insert property into property list class */ - if(H5P_add_prop(plist->props,new_prop)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); - - /* Increment property count for class */ - plist->nprops++; - -done: - if(ret_value==FAIL) { - if(new_prop!=NULL) { - if(new_prop->name!=NULL) - H5MM_xfree(new_prop->name); - if(new_prop->value!=NULL) - H5MM_xfree(new_prop->value); - H5FL_FREE(H5P_genprop_t,new_prop); - } /* end if */ - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_insert() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pinsert - PURPOSE - Routine to insert a new property in a property list. - USAGE - herr_t H5Pinsert(plist, name, size, value, prp_set, prp_get, prp_close) - hid_t plist; IN: Property list to add property to - const char *name; IN: Name of property to add - size_t size; IN: Size of property in bytes - void *value; IN: Pointer to the value for the property - H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback - H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback - H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback - H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback - H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback - H5P_prp_close_func_t prp_close; IN: Function pointer to property close - callback - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Inserts a temporary property into a property list. The property will - exist only in this property list object. The name of the property must not - already exist. The value must be provided unless the property is zero- - sized. Any of the callback routines may be set to NULL if they are not - needed. - - Zero-sized properties are allowed and do not store any data in the - property list. These may be used as flags to indicate the presence or - absence of a particular piece of information. The 'value' pointer for a - zero-sized property may be set to NULL. The property 'close' callback is - called for zero-sized properties, but the 'set' and 'get' callbacks are - never called. - - The 'set' callback is called before a new value is copied into the - property. H5P_prp_set_func_t is defined as: - typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being modified. - const char *name; IN: The name of the property being modified. - size_t size; IN: The size of the property value - void *new_value; IN/OUT: The value being set for the property. - The 'set' routine may modify the value to be set and those changes will be - stored as the value of the property. If the 'set' routine returns a - negative value, the new property value is not copied into the property and - the property list set routine returns an error value. - - The 'get' callback is called before a value is retrieved from the - property. H5P_prp_get_func_t is defined as: - typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list being queried. - const char *name; IN: The name of the property being queried. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value being retrieved for the property. - The 'get' routine may modify the value to be retrieved and those changes - will be returned to the calling function. If the 'get' routine returns a - negative value, the property value is returned and the property list get - routine returns an error value. - - The 'delete' callback is called when a property is deleted from a - property list. H5P_prp_del_func_t is defined as: - typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, - size_t size, void *value); - where the parameters to the callback function are: - hid_t prop_id; IN: The ID of the property list the property is deleted from. - const char *name; IN: The name of the property being deleted. - size_t size; IN: The size of the property value - void *value; IN/OUT: The value of the property being deleted. - The 'delete' routine may modify the value passed in, but the value is not - used by the library when the 'delete' routine returns. If the - 'delete' routine returns a negative value, the property list deletion - routine returns an error value but the property is still deleted. - - The 'copy' callback is called when a property list with this - property is copied. H5P_prp_copy_func_t is defined as: - typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being copied. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being copied. - The 'copy' routine may modify the value to be copied and those changes will be - stored as the value of the property. If the 'copy' routine returns a - negative value, the new property value is not copied into the property and - the property list copy routine returns an error value. - - The 'compare' callback is called when a property list with this - property is compared to another property list. H5P_prp_compare_func_t is - defined as: - typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, - size_t size); - where the parameters to the callback function are: - const void *value1; IN: The value of the first property being compared. - const void *value2; IN: The value of the second property being compared. - size_t size; IN: The size of the property value - The 'compare' routine may not modify the values to be compared. The - 'compare' routine should return a positive value if VALUE1 is greater than - VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 - and VALUE2 are equal. - - The 'close' callback is called when a property list with this - property is being destroyed. H5P_prp_close_func_t is defined as: - typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, - void *value); - where the parameters to the callback function are: - const char *name; IN: The name of the property being closed. - size_t size; IN: The size of the property value - void *value; IN: The value of the property being closed. - The 'close' routine may modify the value passed in, but the value is not - used by the library when the 'close' routine returns. If the - 'close' routine returns a negative value, the property list close - routine returns an error value but the property list is still closed. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - The 'set' callback function may be useful to range check the value being - set for the property or may perform some tranformation/translation of the - value set. The 'get' callback would then [probably] reverse the - transformation, etc. A single 'get' or 'set' callback could handle - multiple properties by performing different actions based on the property - name or other properties in the property list. - - There is no 'create' callback routine for temporary property list - objects, the initial value is assumed to have any necessary setup already - performed on it. - - I would like to say "the property list is not closed" when a 'close' - routine fails, but I don't think that's possible due to other properties in - the list being successfully closed & removed from the property list. I - suppose that it would be possible to just remove the properties which have - successful 'close' callbacks, but I'm not happy with the ramifications - of a mangled, un-closable property list hanging around... Any comments? -QAK - - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -#ifdef H5_WANT_H5_V1_6_COMPAT -herr_t -H5Pinsert(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_close_func_t prp_close) -#else /* H5_WANT_H5_V1_6_COMPAT */ -herr_t -H5Pinsert(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) -#endif /* H5_WANT_H5_V1_6_COMPAT */ -{ - H5P_genplist_t *plist; /* Property list to modify */ - herr_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pinsert, FAIL); -#ifdef H5_WANT_H5_V1_6_COMPAT - H5TRACE9("e","iszxxxxxx",plist_id,name,size,value,prp_set,prp_get, - prp_delete,prp_copy,prp_close); -#else /* H5_WANT_H5_V1_6_COMPAT */ - H5TRACE10("e","iszxxxxxxx",plist_id,name,size,value,prp_set,prp_get, - prp_delete,prp_copy,prp_cmp,prp_close); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - - /* Check arguments. */ - if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - if (size>0 && value==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); - - /* Create the new property list class */ -#ifdef H5_WANT_H5_V1_6_COMPAT - if ((ret_value=H5P_insert(plist,name,size,value,prp_set,prp_get,prp_delete,prp_copy,NULL,prp_close))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in plist"); -#else /* H5_WANT_H5_V1_6_COMPAT */ - if ((ret_value=H5P_insert(plist,name,size,value,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in plist"); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pinsert() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_set - PURPOSE - Internal routine to set a property's value in a property list. - USAGE - herr_t H5P_set(plist, name, value) - H5P_genplist_t *plist; IN: Property list to find property in - const char *name; IN: Name of property to set - void *value; IN: Pointer to the value for the property - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Sets a new value for a property in a property list. The property name - must exist or this routine will fail. If there is a 'set' callback routine - registered for this property, the 'value' will be passed to that routine and - any changes to the 'value' will be used when setting the property value. - The information pointed at by the 'value' pointer (possibly modified by the - 'set' callback) is copied into the property list value and may be changed - by the application making the H5Pset call without affecting the property - value. - - If the 'set' callback routine returns an error, the property value will - not be modified. This routine may not be called for zero-sized properties - and will return an error in that case. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_set(H5P_genplist_t *plist, const char *name, const void *value) -{ - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_set, FAIL); - - assert(plist); - assert(name); - assert(value); - - /* Check if the property has been deleted */ - if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); - - /* Find property in changed list */ - if((prop=H5SL_search(plist->props,name))!=NULL) { - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size"); - - /* Make a copy of the value and pass to 'set' callback */ - if(prop->set!=NULL) { - void *tmp_value; /* Temporary value for property */ - - /* Make a copy of the current value, in case the callback fails */ - if (NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); - HDmemcpy(tmp_value,value,prop->size); - - /* Call user's callback */ - if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value)<0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); - } /* end if */ - - /* Copy new [possibly unchanged] value into property value */ - HDmemcpy(prop->value,tmp_value,prop->size); - - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'set' callback, just copy value */ - else - HDmemcpy(prop->value,value,prop->size); - } /* end if */ - else { - /* - * Check if we should set class properties (up through list of parent classes also), - * & make property 'set' callback. - */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Find the property in the class */ - if((prop=H5SL_search(tclass->props,name))!=NULL) { - H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */ - - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size"); - - /* Make a copy of the value and pass to 'set' callback */ - if(prop->set!=NULL) { - void *tmp_value; /* Temporary value for property */ - - /* Make a copy of the current value, in case the callback fails */ - if (NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); - HDmemcpy(tmp_value,value,prop->size); - - /* Call user's callback */ - if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value)<0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); - } /* end if */ - - if(HDmemcmp(tmp_value,prop->value,prop->size)) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); - - /* Copy new value into property value */ - HDmemcpy(pcopy->value,tmp_value,pcopy->size); - - /* Insert the changed property into the property list */ - if(H5P_add_prop(plist->props,pcopy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); - } /* end if */ - - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'set' callback, just copy value */ - else { - if(HDmemcmp(value,prop->value,prop->size)) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); - - HDmemcpy(pcopy->value,value,pcopy->size); - - /* Insert the changed property into the property list */ - if(H5P_add_prop(plist->props,pcopy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); - } /* end if */ - } /* end else */ - - /* Leave */ - HGOTO_DONE(SUCCEED); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* If we get this far, then it wasn't in the list of changed properties, - * nor in the properties in the class hierarchy, indicate an error - */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_set() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pset - PURPOSE - Routine to set a property's value in a property list. - USAGE - herr_t H5P_set(plist_id, name, value) - hid_t plist_id; IN: Property list to find property in - const char *name; IN: Name of property to set - void *value; IN: Pointer to the value for the property - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Sets a new value for a property in a property list. The property name - must exist or this routine will fail. If there is a 'set' callback routine - registered for this property, the 'value' will be passed to that routine and - any changes to the 'value' will be used when setting the property value. - The information pointed at by the 'value' pointer (possibly modified by the - 'set' callback) is copied into the property list value and may be changed - by the application making the H5Pset call without affecting the property - value. - - If the 'set' callback routine returns an error, the property value will - not be modified. This routine may not be called for zero-sized properties - and will return an error in that case. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5Pset(hid_t plist_id, const char *name, void *value) -{ - H5P_genplist_t *plist; /* Property list to modify */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset, FAIL); - H5TRACE3("e", "i*s*x", plist_id, name, value); - - /* Check arguments. */ - if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - if (value==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value"); - - /* Go set the value */ - if(H5P_set(plist,name,value)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to set value in plist"); - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pset() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_exist_plist - PURPOSE - Internal routine to query the existance of a property in a property list. - USAGE - herr_t H5P_exist_plist(plist, name) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to check for - RETURNS - Success: Positive if the property exists in the property list, zero - if the property does not exist. - Failure: negative value - DESCRIPTION - This routine checks if a property exists within a property list. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -htri_t -H5P_exist_plist(H5P_genplist_t *plist, const char *name) -{ - htri_t ret_value=FAIL; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_plist); - - assert(plist); - assert(name); - - /* Check for property in deleted property list */ - if(H5SL_search(plist->del,name)!=NULL) - ret_value=0; - else { - /* Check for property in changed property list */ - if(H5SL_search(plist->props,name)!=NULL) - ret_value=1; - else { - H5P_genclass_t *tclass; /* Temporary class pointer */ - - tclass=plist->pclass; - while(tclass!=NULL) { - if(H5SL_search(tclass->props,name)!=NULL) - HGOTO_DONE(1); - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* If we've reached here, we couldn't find the property */ - ret_value=0; - } /* end else */ - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_exist_plist() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_exist_pclass - PURPOSE - Internal routine to query the existance of a property in a property class. - USAGE - herr_t H5P_exist_pclass(pclass, name) - H5P_genclass_t *pclass; IN: Property class to check - const char *name; IN: Name of property to check for - RETURNS - Success: Positive if the property exists in the property list, zero - if the property does not exist. - Failure: negative value - DESCRIPTION - This routine checks if a property exists within a property list. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static htri_t -H5P_exist_pclass(H5P_genclass_t *pclass, const char *name) -{ - htri_t ret_value=FAIL; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_pclass); - - assert(pclass); - assert(name); - - /* Check for property in property list */ - if(H5SL_search(pclass->props,name)==NULL) - ret_value=0; - else - ret_value=1; - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_exist_pclass() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pexist - PURPOSE - Routine to query the existance of a property in a property object. - USAGE - htri_t H5P_exist(id, name) - hid_t id; IN: Property object ID to check - const char *name; IN: Name of property to check for - RETURNS - Success: Positive if the property exists in the property object, zero - if the property does not exist. - Failure: negative value - DESCRIPTION - This routine checks if a property exists within a property list or - class. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -htri_t -H5Pexist(hid_t id, const char *name) -{ - H5P_genplist_t *plist; /* Property list to query */ - H5P_genclass_t *pclass; /* Property class to query */ - htri_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pexist, FAIL); - H5TRACE2("t", "i*s", id, name); - - /* Check arguments. */ - if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - - /* Check for the existance of the property in the list or class */ - if(H5I_GENPROP_LST == H5I_get_type(id)) { - if (NULL == (plist = H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if ((ret_value=H5P_exist_plist(plist,name))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in list"); - } /* end if */ - else - if(H5I_GENPROP_CLS == H5I_get_type(id)) { - if (NULL == (pclass = H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); - if ((ret_value=H5P_exist_pclass(pclass,name))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in class"); - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pexist() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_get_size_plist - PURPOSE - Internal routine to query the size of a property in a property list. - USAGE - herr_t H5P_get_size_plist(plist, name) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query - size_t *size; OUT: Size of property - RETURNS - Success: non-negative value - Failure: negative value - DESCRIPTION - This routine retrieves the size of a property's value in bytes. Zero- - sized properties are allowed and return a value of 0. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_get_size_plist(H5P_genplist_t *plist, const char *name, size_t *size) -{ - H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_plist); - - assert(plist); - assert(name); - assert(size); - - /* Find property */ - if((prop=H5P_find_prop_plist(plist,name))==NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); - - /* Get property size */ - *size=prop->size; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_get_size_plist() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_get_size_pclass - PURPOSE - Internal routine to query the size of a property in a property class. - USAGE - herr_t H5P_get_size_pclass(pclass, name) - H5P_genclass_t *pclass; IN: Property class to check - const char *name; IN: Name of property to query - size_t *size; OUT: Size of property - RETURNS - Success: non-negative value - Failure: negative value - DESCRIPTION - This routine retrieves the size of a property's value in bytes. Zero- - sized properties are allowed and return a value of 0. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, size_t *size) -{ - H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_pclass); - - assert(pclass); - assert(name); - assert(size); - - /* Find property */ - if((prop=H5P_find_prop_pclass(pclass,name))==NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); - - /* Get property size */ - *size=prop->size; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_get_size_pclass() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pget_size - PURPOSE - Routine to query the size of a property in a property list or class. - USAGE - herr_t H5Pget_size(id, name) - hid_t id; IN: ID of property list or class to check - const char *name; IN: Name of property to query - size_t *size; OUT: Size of property - RETURNS - Success: non-negative value - Failure: negative value - DESCRIPTION - This routine retrieves the size of a property's value in bytes. Zero- - sized properties are allowed and return a value of 0. This function works - for both property lists and classes. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5Pget_size(hid_t id, const char *name, size_t *size) -{ - H5P_genclass_t *pclass; /* Property class to query */ - H5P_genplist_t *plist; /* Property list to query */ - herr_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pget_size, FAIL); - H5TRACE3("e", "i*s*z", id, name, size); - - /* Check arguments. */ - if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - if (size==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property size"); - - if (H5I_GENPROP_LST == H5I_get_type(id)) { - if (NULL == (plist = H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - - /* Check the property size */ - if ((ret_value=H5P_get_size_plist(plist,name,size))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist"); - } /* end if */ - else - if (H5I_GENPROP_CLS == H5I_get_type(id)) { - if (NULL == (pclass = H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - - /* Check the property size */ - if ((ret_value=H5P_get_size_pclass(pclass,name,size))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist"); - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pget_size() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_get_class - PURPOSE - Internal routine to query the class of a generic property list - USAGE - H5P_genclass_t *H5P_get_class(plist) - H5P_genplist_t *plist; IN: Property list to check - RETURNS - Success: Pointer to the class for a property list - Failure: NULL - DESCRIPTION - This routine retrieves a pointer to the class for a property list. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5P_genclass_t * -H5P_get_class(H5P_genplist_t *plist) -{ - H5P_genclass_t *ret_value; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class); - - assert(plist); - - /* Get property size */ - ret_value=plist->pclass; - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_get_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pget_class - PURPOSE - Routine to query the class of a generic property list - USAGE - hid_t H5Pget_class(plist_id) - hid_t plist_id; IN: Property list to query - RETURNS - Success: ID of class object - Failure: negative - DESCRIPTION - This routine retrieves the class of a property list. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Change the name of this function to H5Pget_class (and remove old H5Pget_class) - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -hid_t -H5Pget_class(hid_t plist_id) -{ - H5P_genplist_t *plist; /* Property list to query */ - H5P_genclass_t *pclass=NULL; /* Property list class */ - hid_t ret_value=FAIL; /* return value */ - - FUNC_ENTER_API(H5Pget_class, FAIL); - H5TRACE1("i", "i", plist_id); - - /* Check arguments. */ - if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - - /* Retrieve the property list class */ - if ((pclass=H5P_get_class(plist))==NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list"); - - /* Increment the outstanding references to the class object */ - if(H5P_access_class(pclass,H5P_MOD_INC_REF)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count"); - - /* Get an atom for the class */ - if ((ret_value = H5I_register(H5I_GENPROP_CLS, pclass))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); - -done: - if (ret_value<0 && pclass) - H5P_close_class(pclass); - - FUNC_LEAVE_API(ret_value); -} /* H5Pget_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_get_nprops_plist - PURPOSE - Internal routine to query the number of properties in a property list - USAGE - herr_t H5P_get_nprops_plist(plist, nprops) - H5P_genplist_t *plist; IN: Property list to check - size_t *nprops; OUT: Number of properties in the property list - RETURNS - Success: non-negative value - Failure: negative value - DESCRIPTION - This routine retrieves the number of a properties in a property list. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_get_nprops_plist(H5P_genplist_t *plist, size_t *nprops) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_nprops_plist); - - assert(plist); - assert(nprops); - - /* Get property size */ - *nprops=plist->nprops; - - FUNC_LEAVE_NOAPI(SUCCEED); -} /* H5P_get_nprops_plist() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_get_nprops_pclass - PURPOSE - Internal routine to query the number of properties in a property class - USAGE - herr_t H5P_get_nprops_pclass(pclass, nprops) - H5P_genclass_t *pclass; IN: Property class to check - size_t *nprops; OUT: Number of properties in the property list - hbool_t recurse; IN: Include properties in parent class(es) also - RETURNS - Success: non-negative value (can't fail) - Failure: negative value - DESCRIPTION - This routine retrieves the number of a properties in a property class. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_get_nprops_pclass(H5P_genclass_t *pclass, size_t *nprops, hbool_t recurse) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_get_nprops_pclass, FAIL) - - assert(pclass); - assert(nprops); - - /* Get number of properties */ - *nprops=pclass->nprops; - - /* Check if the class is derived, and walk up the chain, if so */ - if(recurse) - while(pclass->parent!=NULL) { - pclass = pclass->parent; - *nprops += pclass->nprops; - } /* end while */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5P_get_nprops_pclass() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pget_nprops - PURPOSE - Routine to query the size of a property in a property list or class. - USAGE - herr_t H5Pget_nprops(id, nprops) - hid_t id; IN: ID of Property list or class to check - size_t *nprops; OUT: Number of properties in the property object - RETURNS - Success: non-negative value - Failure: negative value - DESCRIPTION - This routine retrieves the number of properties in a property list or - class. If a property class ID is given, the number of registered properties - in the class is returned in NPROPS. If a property list ID is given, the - current number of properties in the list is returned in NPROPS. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5Pget_nprops(hid_t id, size_t *nprops) -{ - H5P_genplist_t *plist; /* Property list to query */ - H5P_genclass_t *pclass; /* Property class to query */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pget_nprops, FAIL); - H5TRACE2("e", "i*z", id, nprops); - - /* Check arguments. */ - if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - if (nprops==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property nprops pointer"); - - if(H5I_GENPROP_LST == H5I_get_type(id)) { - if (NULL == (plist = H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if (H5P_get_nprops_plist(plist,nprops)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in plist"); - } /* end if */ - else - if(H5I_GENPROP_CLS == H5I_get_type(id)) { - if (NULL == (pclass = H5I_object(id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); - if (H5P_get_nprops_pclass(pclass,nprops,FALSE)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in pclass"); - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pget_nprops() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_cmp_prop - PURPOSE - Internal routine to compare two generic properties - USAGE - int H5P_cmp_prop(prop1, prop2) - H5P_genprop_t *prop1; IN: 1st property to compare - H5P_genprop_t *prop1; IN: 2nd property to compare - RETURNS - Success: negative if prop1 "less" than prop2, positive if prop1 "greater" - than prop2, zero if prop1 is "equal" to prop2 - Failure: can't fail - DESCRIPTION - This function compares two generic properties together to see if - they are the same property. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static int -H5P_cmp_prop(H5P_genprop_t *prop1, H5P_genprop_t *prop2) -{ - int cmp_value; /* Value from comparison */ - int ret_value=0; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_prop); - - assert(prop1); - assert(prop2); - - /* Check the name */ - if((cmp_value=HDstrcmp(prop1->name,prop2->name))!=0) - HGOTO_DONE(cmp_value); - - /* Check the size of properties */ - if(prop1->size < prop2->size) HGOTO_DONE(-1); - if(prop1->size > prop2->size) HGOTO_DONE(1); - - /* Check if they both have the same 'create' callback */ - if(prop1->create==NULL && prop2->create!=NULL) HGOTO_DONE(-1); - if(prop1->create!=NULL && prop2->create==NULL) HGOTO_DONE(1); - if(prop1->create!=prop2->create) HGOTO_DONE(-1); - - /* Check if they both have the same 'set' callback */ - if(prop1->set==NULL && prop2->set!=NULL) HGOTO_DONE(-1); - if(prop1->set!=NULL && prop2->set==NULL) HGOTO_DONE(1); - if(prop1->set!=prop2->set) HGOTO_DONE(-1); - - /* Check if they both have the same 'get' callback */ - if(prop1->get==NULL && prop2->get!=NULL) HGOTO_DONE(-1); - if(prop1->get!=NULL && prop2->get==NULL) HGOTO_DONE(1); - if(prop1->get!=prop2->get) HGOTO_DONE(-1); - - /* Check if they both have the same 'delete' callback */ - if(prop1->del==NULL && prop2->del!=NULL) HGOTO_DONE(-1); - if(prop1->del!=NULL && prop2->del==NULL) HGOTO_DONE(1); - if(prop1->del!=prop2->del) HGOTO_DONE(-1); - - /* Check if they both have the same 'copy' callback */ - if(prop1->copy==NULL && prop2->copy!=NULL) HGOTO_DONE(-1); - if(prop1->copy!=NULL && prop2->copy==NULL) HGOTO_DONE(1); - if(prop1->copy!=prop2->copy) HGOTO_DONE(-1); - - /* Check if they both have the same 'compare' callback */ - if(prop1->cmp==NULL && prop2->cmp!=NULL) HGOTO_DONE(-1); - if(prop1->cmp!=NULL && prop2->cmp==NULL) HGOTO_DONE(1); - if(prop1->cmp!=prop2->cmp) HGOTO_DONE(-1); - - /* Check if they both have the same 'close' callback */ - if(prop1->close==NULL && prop2->close!=NULL) HGOTO_DONE(-1); - if(prop1->close!=NULL && prop2->close==NULL) HGOTO_DONE(1); - if(prop1->close!=prop2->close) HGOTO_DONE(-1); - - /* Check if they both have values allocated (or not allocated) */ - if(prop1->value==NULL && prop2->value!=NULL) HGOTO_DONE(-1); - if(prop1->value!=NULL && prop2->value==NULL) HGOTO_DONE(1); - if(prop1->value!=NULL) { - /* Call comparison routine */ - if((cmp_value=prop1->cmp(prop1->value,prop2->value,prop1->size))!=0) - HGOTO_DONE(cmp_value); - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_cmp_prop() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_cmp_class - PURPOSE - Internal routine to compare two generic property classes - USAGE - int H5P_cmp_class(pclass1, pclass2) - H5P_genclass_t *pclass1; IN: 1st property class to compare - H5P_genclass_t *pclass2; IN: 2nd property class to compare - RETURNS - Success: negative if class1 "less" than class2, positive if class1 "greater" - than class2, zero if class1 is "equal" to class2 - Failure: can't fail - DESCRIPTION - This function compares two generic property classes together to see if - they are the same class. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static int -H5P_cmp_class(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2) -{ - H5SL_node_t *tnode1,*tnode2; /* Temporary pointer to property nodes */ - int cmp_value; /* Value from comparison */ - int ret_value=0; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_class); - - assert(pclass1); - assert(pclass2); - - /* Use the revision number to quickly check for identical classes */ - if(pclass1->revision==pclass2->revision) - HGOTO_DONE(0); - - /* Check the name */ - if((cmp_value=HDstrcmp(pclass1->name,pclass2->name))!=0) - HGOTO_DONE(cmp_value); - - /* Check the number of properties */ - if(pclass1->nprops < pclass2->nprops) HGOTO_DONE(-1); - if(pclass1->nprops > pclass2->nprops) HGOTO_DONE(1); - - /* Check the number of property lists created from the class */ - if(pclass1->plists < pclass2->plists) HGOTO_DONE(-1); - if(pclass1->plists > pclass2->plists) HGOTO_DONE(1); - - /* Check the number of classes derived from the class */ - if(pclass1->classes < pclass2->classes) HGOTO_DONE(-1); - if(pclass1->classes > pclass2->classes) HGOTO_DONE(1); - - /* Check the number of ID references open on the class */ - if(pclass1->ref_count < pclass2->ref_count) HGOTO_DONE(-1); - if(pclass1->ref_count > pclass2->ref_count) HGOTO_DONE(1); - - /* Check whether they are internal or not */ - if(pclass1->internal < pclass2->internal) HGOTO_DONE(-1); - if(pclass1->internal > pclass2->internal) HGOTO_DONE(1); - - /* Check whether they are deleted or not */ - if(pclass1->deleted < pclass2->deleted) HGOTO_DONE(-1); - if(pclass1->deleted > pclass2->deleted) HGOTO_DONE(1); - - /* Check whether they have creation callback functions & data */ - if(pclass1->create_func==NULL && pclass2->create_func!=NULL) HGOTO_DONE(-1); - if(pclass1->create_func!=NULL && pclass2->create_func==NULL) HGOTO_DONE(1); - if(pclass1->create_func!=pclass2->create_func) HGOTO_DONE(-1); - if(pclass1->create_data < pclass2->create_data) HGOTO_DONE(-1); - if(pclass1->create_data > pclass2->create_data) HGOTO_DONE(1); - - /* Check whether they have close callback functions & data */ - if(pclass1->close_func==NULL && pclass2->close_func!=NULL) HGOTO_DONE(-1); - if(pclass1->close_func!=NULL && pclass2->close_func==NULL) HGOTO_DONE(1); - if(pclass1->close_func!=pclass2->close_func) HGOTO_DONE(-1); - if(pclass1->close_data < pclass2->close_data) HGOTO_DONE(-1); - if(pclass1->close_data > pclass2->close_data) HGOTO_DONE(1); - - /* Cycle through the properties and compare them also */ - tnode1=H5SL_first(pclass1->props); - tnode2=H5SL_first(pclass2->props); - while(tnode1 || tnode2) { - H5P_genprop_t *prop1, *prop2; /* Property for node */ - - /* Check if they both have properties in this skip list node */ - if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1); - if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1); - - /* Compare the two properties */ - prop1=H5SL_item(tnode1); - prop2=H5SL_item(tnode2); - if((cmp_value=H5P_cmp_prop(prop1,prop2))!=0) - HGOTO_DONE(cmp_value); - - /* Advance the pointers */ - tnode1=H5SL_next(tnode1); - tnode2=H5SL_next(tnode2); - } /* end while */ - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_cmp_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_cmp_plist - PURPOSE - Internal routine to compare two generic property lists - USAGE - int H5P_cmp_plist(plist1, plist2) - H5P_genplist_t *plist1; IN: 1st property list to compare - H5P_genplist_t *plist2; IN: 2nd property list to compare - RETURNS - Success: negative if list1 "less" than list2, positive if list1 "greater" - than list2, zero if list1 is "equal" to list2 - Failure: can't fail - DESCRIPTION - This function compares two generic property lists together to see if - they are the same list. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static int -H5P_cmp_plist(H5P_genplist_t *plist1, H5P_genplist_t *plist2) -{ - H5SL_node_t *tnode1,*tnode2; /* Temporary pointer to property nodes */ - int cmp_value; /* Value from comparison */ - int ret_value=0; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_plist); - - assert(plist1); - assert(plist2); - - /* Check the number of properties */ - if(plist1->nprops < plist2->nprops) HGOTO_DONE(-1); - if(plist1->nprops > plist2->nprops) HGOTO_DONE(1); - - /* Check whether they've been initialized */ - if(plist1->class_init < plist2->class_init) HGOTO_DONE(-1); - if(plist1->class_init > plist2->class_init) HGOTO_DONE(1); - - /* Check for identical deleted properties */ - if(H5SL_count(plist1->del)>0) { - /* Check for no deleted properties in plist2 */ - if(H5SL_count(plist2->del)==0) HGOTO_DONE(1); - - tnode1=H5SL_first(plist1->del); - tnode2=H5SL_first(plist2->del); - while(tnode1 || tnode2) { - const char *name1, *name2; /* Name for node */ - - /* Check if they both have properties in this node */ - if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1); - if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1); - - /* Compare the two deleted properties */ - name1=H5SL_item(tnode1); - name2=H5SL_item(tnode2); - if((cmp_value=HDstrcmp(name1,name2))!=0) - HGOTO_DONE(cmp_value); - - /* Advance the pointers */ - tnode1=H5SL_next(tnode1); - tnode2=H5SL_next(tnode2); - } /* end while */ - } /* end if */ - else - if(H5SL_count(plist2->del)>0) HGOTO_DONE (-1); - - /* Cycle through the changed properties and compare them also */ - if(H5SL_count(plist1->props)>0) { - /* Check for no changed properties in plist2 */ - if(H5SL_count(plist2->props)==0) HGOTO_DONE(1); - - tnode1=H5SL_first(plist1->props); - tnode2=H5SL_first(plist2->props); - while(tnode1 || tnode2) { - H5P_genprop_t *prop1, *prop2; /* Property for node */ - - /* Check if they both have properties in this node */ - if(tnode1==NULL && tnode2!=NULL) HGOTO_DONE(-1); - if(tnode1!=NULL && tnode2==NULL) HGOTO_DONE(1); - - /* Compare the two properties */ - prop1=H5SL_item(tnode1); - prop2=H5SL_item(tnode2); - if((cmp_value=H5P_cmp_prop(prop1,prop2))!=0) - HGOTO_DONE(cmp_value); - - /* Advance the pointers */ - tnode1=H5SL_next(tnode1); - tnode2=H5SL_next(tnode2); - } /* end while */ - } /* end if */ - else - if(H5SL_count(plist2->props)>0) HGOTO_DONE (-1); - - /* Check the parent classes */ - if((cmp_value=H5P_cmp_class(plist1->pclass,plist2->pclass))!=0) - HGOTO_DONE(cmp_value); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_cmp_plist() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pequal - PURPOSE - Routine to query whether two property lists or two property classes are equal - USAGE - htri_t H5Pequal(id1, id2) - hid_t id1; IN: Property list or class ID to compare - hid_t id2; IN: Property list or class ID to compare - RETURNS - Success: TRUE if equal, FALSE if unequal - Failure: negative - DESCRIPTION - Determines whether two property lists or two property classes are equal. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -htri_t -H5Pequal(hid_t id1, hid_t id2) -{ - void *obj1, *obj2; /* Property objects to compare */ - htri_t ret_value = FALSE; /* return value */ - - FUNC_ENTER_API(H5Pequal, FAIL) - H5TRACE2("t", "ii", id1, id2); - - /* Check arguments. */ - if((H5I_GENPROP_LST != H5I_get_type(id1) && H5I_GENPROP_CLS != H5I_get_type(id1)) - || (H5I_GENPROP_LST != H5I_get_type(id2) && H5I_GENPROP_CLS != H5I_get_type(id2))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects") - if(H5I_get_type(id1) != H5I_get_type(id2)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects") - if(NULL == (obj1 = H5I_object(id1)) || NULL == (obj2 = H5I_object(id2))) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist") - - /* Compare property lists */ - if(H5I_GENPROP_LST == H5I_get_type(id1)) { - if(H5P_cmp_plist(obj1, obj2) == 0) - ret_value = TRUE; - } /* end if */ - /* Must be property classes */ - else { - if(H5P_cmp_class(obj1, obj2) == 0) - ret_value = TRUE; - } /* end else */ - -done: - FUNC_LEAVE_API(ret_value) -} /* H5Pequal() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_isa_class_real - PURPOSE - Internal routine to query whether a property class is the same as another - class. - USAGE - htri_t H5P_isa_class_real(pclass1, pclass2) - H5P_genclass_t *pclass1; IN: Property class to check - H5P_genclass_t *pclass2; IN: Property class to compare with - RETURNS - Success: TRUE (1) or FALSE (0) - Failure: negative value - DESCRIPTION - This routine queries whether a property class is the same as another class, - and walks up the hierarchy of derived classes, checking if the first class - is derived from the second class also. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static htri_t -H5P_isa_class_real(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2) -{ - htri_t ret_value; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_isa_class_real); - - assert(pclass1); - assert(pclass2); - - /* Compare property classes */ - if(H5P_cmp_class(pclass1,pclass2)==0) { - HGOTO_DONE(TRUE); - } else { - /* Check if the class is derived, and walk up the chain, if so */ - if(pclass1->parent!=NULL) - ret_value=H5P_isa_class_real(pclass1->parent,pclass2); - else - HGOTO_DONE(FALSE); - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_isa_class_real() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_isa_class - PURPOSE - Internal routine to query whether a property list is a certain class - USAGE - hid_t H5P_isa_class(plist_id, pclass_id) - hid_t plist_id; IN: Property list to query - hid_t pclass_id; IN: Property class to query - RETURNS - Success: TRUE (1) or FALSE (0) - Failure: negative - DESCRIPTION - This routine queries whether a property list is a member of the property - list class. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This function is special in that it is an internal library function, but - accepts hid_t's as parameters. Since it is used in basically the same way - as the H5I functions, this should be OK. Don't make more library functions - which accept hid_t's without thorough discussion. -QAK - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -htri_t -H5P_isa_class(hid_t plist_id, hid_t pclass_id) -{ - H5P_genplist_t *plist; /* Property list to query */ - H5P_genclass_t *pclass; /* Property list class */ - htri_t ret_value; /* return value */ - - FUNC_ENTER_NOAPI(H5P_isa_class, FAIL); - - /* Check arguments. */ - if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); - - /* Compare the property list's class against the other class */ - if ((ret_value = H5P_isa_class_real(plist->pclass, pclass))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_isa_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Pisa_class - PURPOSE - Routine to query whether a property list is a certain class - USAGE - hid_t H5Pisa_class(plist_id, pclass_id) - hid_t plist_id; IN: Property list to query - hid_t pclass_id; IN: Property class to query - RETURNS - Success: TRUE (1) or FALSE (0) - Failure: negative - DESCRIPTION - This routine queries whether a property list is a member of the property - list class. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - What about returning a value indicating that the property class is further - up the class hierarchy? - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -htri_t -H5Pisa_class(hid_t plist_id, hid_t pclass_id) -{ - htri_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pisa_class, FAIL); - H5TRACE2("t", "ii", plist_id, pclass_id); - - /* Check arguments. */ - if (H5I_GENPROP_LST != H5I_get_type(plist_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if (H5I_GENPROP_CLS != H5I_get_type(pclass_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); - - /* Compare the property list's class against the other class */ - if ((ret_value = H5P_isa_class(plist_id, pclass_id))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes"); - -done: - FUNC_LEAVE_API(ret_value); -} /* H5Pisa_class() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_object_verify - PURPOSE - Internal routine to query whether a property list is a certain class and - retrieve the property list object associated with it. - USAGE - void *H5P_object_verify(plist_id, pclass_id) - hid_t plist_id; IN: Property list to query - hid_t pclass_id; IN: Property class to query - RETURNS - Success: valid pointer to a property list object - Failure: NULL - DESCRIPTION - This routine queries whether a property list is member of a certain class - and retrieves the property list object associated with it. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This function is special in that it is an internal library function, but - accepts hid_t's as parameters. Since it is used in basically the same way - as the H5I functions, this should be OK. Don't make more library functions - which accept hid_t's without thorough discussion. -QAK - - This function is similar (in spirit) to H5I_object_verify() - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -void * -H5P_object_verify(hid_t plist_id, hid_t pclass_id) -{ - void *ret_value; /* return value */ - - FUNC_ENTER_NOAPI(H5P_object_verify, NULL); - - /* Compare the property list's class against the other class */ - if (H5P_isa_class(plist_id,pclass_id)!=TRUE) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, NULL, "property list is not a member of the class"); - - /* Get the plist structure */ - if(NULL == (ret_value = H5I_object(plist_id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_object_verify() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_iterate_plist - PURPOSE - Internal routine to iterate over the properties in a property list - USAGE - herr_t H5P_iterate_plist(plist_id, idx, iter_func, iter_data) - hid_t plist_id; IN: ID of property list to iterate over - int *idx; IN/OUT: Index of the property to begin with - H5P_iterate_t iter_func; IN: Function pointer to function to be - called with each property iterated over. - void *iter_data; IN/OUT: Pointer to iteration data from user - RETURNS - Success: Returns the return value of the last call to ITER_FUNC if it was - non-zero, or zero if all properties have been processed. - Failure: negative value - DESCRIPTION - This routine iterates over the properties in the property object specified -with PLIST_ID. For each property in the object, the ITER_DATA and some -additional information, specified below, are passed to the ITER_FUNC function. -The iteration begins with the IDX property in the object and the next element -to be processed by the operator is returned in IDX. If IDX is NULL, then the -iterator starts at the first property; since no stopping point is returned in -this case, the iterator cannot be restarted if one of the calls to its operator -returns non-zero. - -The prototype for H5P_iterate_t is: - typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); -The operation receives the property list or class identifier for the object -being iterated over, ID, the name of the current property within the object, -NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA. - -The return values from an operator are: - Zero causes the iterator to continue, returning zero when all properties - have been processed. - Positive causes the iterator to immediately return that positive value, - indicating short-circuit success. The iterator can be restarted at the - index of the next property. - Negative causes the iterator to immediately return that value, indicating - failure. The iterator can be restarted at the index of the next - property. - -H5Piterate assumes that the properties in the object identified by ID remains -unchanged through the iteration. If the membership changes during the -iteration, the function's behavior is undefined. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static int -H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_data) -{ - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genplist_t *plist; /* Property list pointer */ - H5P_genprop_t *tmp; /* Temporary pointer to properties */ - H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */ - H5SL_node_t *curr_node; /* Current node in skip list */ - int curr_idx=0; /* Current iteration index */ - int ret_value=FAIL; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_plist); - - assert(idx); - assert(iter_func); - - /* Get the property list object */ - if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - - /* Create the skip list to hold names of properties already seen */ - if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); - - /* Walk through the changed properties in the list */ - if(H5SL_count(plist->props) > 0) { - curr_node = H5SL_first(plist->props); - while(curr_node != NULL) { - /* Get pointer to property from node */ - tmp = H5SL_item(curr_node); - - /* Check if we've found the correctly indexed property */ - if(curr_idx>=*idx) { - /* Call the callback function */ - ret_value=(*iter_func)(plist_id,tmp->name,iter_data); - - if(ret_value!=0) - HGOTO_DONE(ret_value); - } /* end if */ - - /* Increment the current index */ - curr_idx++; - - /* Add property name to "seen" list */ - if(H5SL_insert(seen,tmp->name,tmp->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Walk up the class hiearchy */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Walk through the properties in the class */ - curr_node=H5SL_first(tclass->props); - while(curr_node!=NULL) { - /* Get pointer to property from node */ - tmp=H5SL_item(curr_node); - - /* Only call iterator callback for properties we haven't seen - * before and that haven't been deleted - */ - if(H5SL_search(seen,tmp->name)==NULL && - H5SL_search(plist->del,tmp->name)==NULL) { - - - /* Check if we've found the correctly indexed property */ - if(curr_idx>=*idx) { - /* Call the callback function */ - ret_value=(*iter_func)(plist_id,tmp->name,iter_data); - - if(ret_value!=0) - HGOTO_DONE(ret_value); - } /* end if */ - - /* Increment the current index */ - curr_idx++; - - /* Add property name to "seen" list */ - if(H5SL_insert(seen,tmp->name,tmp->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); - } /* end if */ - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - -done: - /* Set the index we stopped at */ - *idx=curr_idx; - - /* Release the skip list of 'seen' properties */ - if(seen!=NULL) - H5SL_close(seen); - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_iterate_plist() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_iterate_pclass - PURPOSE - Internal routine to iterate over the properties in a property class - USAGE - herr_t H5P_iterate_pclass(pclass_id, idx, iter_func, iter_data) - hid_t pclass_id; IN: ID of property class to iterate over - int *idx; IN/OUT: Index of the property to begin with - H5P_iterate_t iter_func; IN: Function pointer to function to be - called with each property iterated over. - void *iter_data; IN/OUT: Pointer to iteration data from user - RETURNS - Success: Returns the return value of the last call to ITER_FUNC if it was - non-zero, or zero if all properties have been processed. - Failure: negative value - DESCRIPTION - This routine iterates over the properties in the property object specified -with PCLASS_ID. For each property in the object, the ITER_DATA and some -additional information, specified below, are passed to the ITER_FUNC function. -The iteration begins with the IDX property in the object and the next element -to be processed by the operator is returned in IDX. If IDX is NULL, then the -iterator starts at the first property; since no stopping point is returned in -this case, the iterator cannot be restarted if one of the calls to its operator -returns non-zero. - -The prototype for H5P_iterate_t is: - typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); -The operation receives the property list or class identifier for the object -being iterated over, ID, the name of the current property within the object, -NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA. - -The return values from an operator are: - Zero causes the iterator to continue, returning zero when all properties - have been processed. - Positive causes the iterator to immediately return that positive value, - indicating short-circuit success. The iterator can be restarted at the - index of the next property. - Negative causes the iterator to immediately return that value, indicating - failure. The iterator can be restarted at the index of the next - property. - -H5Piterate assumes that the properties in the object identified by ID remains -unchanged through the iteration. If the membership changes during the -iteration, the function's behavior is undefined. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static int -H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *iter_data) -{ - H5P_genclass_t *pclass; /* Property list pointer */ - H5SL_node_t *curr_node; /* Current node in skip list */ - H5P_genprop_t *prop; /* Temporary property pointer */ - int curr_idx=0; /* Current iteration index */ - int ret_value=FAIL; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_pclass); - - assert(idx); - assert(iter_func); - - /* Get the property list object */ - if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); - - /* Cycle through the properties and call the callback */ - curr_idx=0; - curr_node=H5SL_first(pclass->props); - while(curr_node!=NULL) { - if(curr_idx>=*idx) { - /* Get the property for the node */ - prop=H5SL_item(curr_node); - - /* Call the callback function */ - ret_value=(*iter_func)(pclass_id,prop->name,iter_data); - - /* Check if iteration function succeeded */ - if(ret_value!=0) - HGOTO_DONE(ret_value); - } /* end if */ - - /* Increment the iteration index */ - curr_idx++; - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - -done: - /* Set the index we stopped at */ - *idx=curr_idx; - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_iterate_pclass() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Piterate - PURPOSE - Routine to iterate over the properties in a property list or class - USAGE - int H5Piterate(pclass_id, idx, iter_func, iter_data) - hid_t id; IN: ID of property object to iterate over - int *idx; IN/OUT: Index of the property to begin with - H5P_iterate_t iter_func; IN: Function pointer to function to be - called with each property iterated over. - void *iter_data; IN/OUT: Pointer to iteration data from user - RETURNS - Success: Returns the return value of the last call to ITER_FUNC if it was - non-zero, or zero if all properties have been processed. - Failure: negative value - DESCRIPTION - This routine iterates over the properties in the property object specified -with ID. The properties in both property lists and classes may be iterated -over with this function. For each property in the object, the ITER_DATA and -some additional information, specified below, are passed to the ITER_FUNC -function. The iteration begins with the IDX property in the object and the -next element to be processed by the operator is returned in IDX. If IDX is -NULL, then the iterator starts at the first property; since no stopping point -is returned in this case, the iterator cannot be restarted if one of the calls -to its operator returns non-zero. The IDX value is 0-based (ie. to start at -the "first" property, the IDX value should be 0). - -The prototype for H5P_iterate_t is: - typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); -The operation receives the property list or class identifier for the object -being iterated over, ID, the name of the current property within the object, -NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA. - -The return values from an operator are: - Zero causes the iterator to continue, returning zero when all properties - have been processed. - Positive causes the iterator to immediately return that positive value, - indicating short-circuit success. The iterator can be restarted at the - index of the next property. - Negative causes the iterator to immediately return that value, indicating - failure. The iterator can be restarted at the index of the next - property. + The 'compare' callback is called when a property list with this + property is compared to another property list. H5P_prp_compare_func_t is + defined as: + typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, + size_t size); + where the parameters to the callback function are: + const void *value1; IN: The value of the first property being compared. + const void *value2; IN: The value of the second property being compared. + size_t size; IN: The size of the property value + The 'compare' routine may not modify the values to be compared. The + 'compare' routine should return a positive value if VALUE1 is greater than + VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 + and VALUE2 are equal. -H5Piterate assumes that the properties in the object identified by ID remains -unchanged through the iteration. If the membership changes during the -iteration, the function's behavior is undefined. + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + There is no 'create' callback routine for temporary property list + objects, the initial value is assumed to have any necessary setup already + performed on it. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -int -H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data) +#ifdef H5_WANT_H5_V1_6_COMPAT +herr_t +H5Pinsert(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_close_func_t prp_close) +#else /* H5_WANT_H5_V1_6_COMPAT */ +herr_t +H5Pinsert(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) +#endif /* H5_WANT_H5_V1_6_COMPAT */ { - int fake_idx=0; /* Index when user doesn't provide one */ - int ret_value; /* return value */ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value; /* return value */ - FUNC_ENTER_API(H5Piterate, FAIL); - H5TRACE4("Is", "i*Isx*x", id, idx, iter_func, iter_data); + FUNC_ENTER_API(H5Pinsert, FAIL); +#ifdef H5_WANT_H5_V1_6_COMPAT + H5TRACE9("e","iszxxxxxx",plist_id,name,size,value,prp_set,prp_get, + prp_delete,prp_copy,prp_close); +#else /* H5_WANT_H5_V1_6_COMPAT */ + H5TRACE10("e","iszxxxxxxx",plist_id,name,size,value,prp_set,prp_get, + prp_delete,prp_copy,prp_cmp,prp_close); +#endif /* H5_WANT_H5_V1_6_COMPAT */ /* Check arguments. */ - if (H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - if (iter_func==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration callback"); + if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if(size>0 && value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); - if (H5I_GENPROP_LST == H5I_get_type(id)) { - /* Iterate over a property list */ - if ((ret_value=H5P_iterate_plist(id,(idx ? idx : &fake_idx),iter_func,iter_data))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over list"); - } /* end if */ - else - if (H5I_GENPROP_CLS == H5I_get_type(id)) { - /* Iterate over a property class */ - if ((ret_value=H5P_iterate_pclass(id,(idx ? idx : &fake_idx),iter_func,iter_data))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over class"); - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); + /* Create the new property list class */ +#ifdef H5_WANT_H5_V1_6_COMPAT + if((ret_value = H5P_insert(plist,name,size,value,prp_set,prp_get,prp_delete,prp_copy,NULL,prp_close)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in plist"); +#else /* H5_WANT_H5_V1_6_COMPAT */ + if((ret_value = H5P_insert(plist,name,size,value,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in plist"); +#endif /* H5_WANT_H5_V1_6_COMPAT */ done: FUNC_LEAVE_API(ret_value); -} /* H5Piterate() */ +} /* H5Pinsert() */ /*-------------------------------------------------------------------------- NAME - H5P_peek_unsigned + H5Pset PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. + Routine to set a property's value in a property list. USAGE - int H5P_peek_unsigned(plist, name) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query + herr_t H5P_set(plist_id, name, value) + hid_t plist_id; IN: Property list to find property in + const char *name; IN: Name of property to set + void *value; IN: Pointer to the value for the property RETURNS - Directly returns the value of the property in the list + Returns non-negative on success, negative on failure. DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. + Sets a new value for a property in a property list. The property name + must exist or this routine will fail. If there is a 'set' callback routine + registered for this property, the 'value' will be passed to that routine and + any changes to the 'value' will be used when setting the property value. + The information pointed at by the 'value' pointer (possibly modified by the + 'set' callback) is copied into the property list value and may be changed + by the application making the H5Pset call without affecting the property + value. + + If the 'set' callback routine returns an error, the property value will + not be modified. This routine may not be called for zero-sized properties + and will return an error in that case. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -unsigned -H5P_peek_unsigned(H5P_genplist_t *plist, const char *name) +herr_t +H5Pset(hid_t plist_id, const char *name, void *value) { - unsigned ret_value; /* return value */ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER_NOAPI(H5P_peek_unsigned, UFAIL); + FUNC_ENTER_API(H5Pset, FAIL); + H5TRACE3("e", "i*s*x", plist_id, name, value); - assert(plist); - assert(name); + /* Check arguments. */ + if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if(value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value"); - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); + /* Go set the value */ + if(H5P_set(plist,name,value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to set value in plist"); done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_peek_unsigned() */ + FUNC_LEAVE_API(ret_value); +} /* H5Pset() */ /*-------------------------------------------------------------------------- NAME - H5P_peek_hid_t + H5Pexist PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. + Routine to query the existance of a property in a property object. USAGE - hid_t H5P_peek_hid_t(plist, name) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query + htri_t H5P_exist(id, name) + hid_t id; IN: Property object ID to check + const char *name; IN: Name of property to check for RETURNS - Directly returns the value of the property in the list + Success: Positive if the property exists in the property object, zero + if the property does not exist. + Failure: negative value DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. + This routine checks if a property exists within a property list or + class. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -hid_t -H5P_peek_hid_t(H5P_genplist_t *plist, const char *name) +htri_t +H5Pexist(hid_t id, const char *name) { - hid_t ret_value; /* return value */ + H5P_genplist_t *plist; /* Property list to query */ + H5P_genclass_t *pclass; /* Property class to query */ + htri_t ret_value; /* return value */ - FUNC_ENTER_NOAPI(H5P_peek_hid_t, FAIL); + FUNC_ENTER_API(H5Pexist, FAIL); + H5TRACE2("t", "i*s", id, name); - assert(plist); - assert(name); + /* Check arguments. */ + if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); + /* Check for the existance of the property in the list or class */ + if(H5I_GENPROP_LST == H5I_get_type(id)) { + if(NULL == (plist = H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if((ret_value = H5P_exist_plist(plist, name)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in list"); + } /* end if */ + else + if(H5I_GENPROP_CLS == H5I_get_type(id)) { + if(NULL == (pclass = H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); + if((ret_value = H5P_exist_pclass(pclass, name)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property does not exist in class"); + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_peek_hid_t() */ + FUNC_LEAVE_API(ret_value); +} /* H5Pexist() */ /*-------------------------------------------------------------------------- NAME - H5P_peek_voidp + H5Pget_size PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. + Routine to query the size of a property in a property list or class. USAGE - void *H5P_peek_voidp(plist, name) - H5P_genplist_t *plist; IN: Property list to check + herr_t H5Pget_size(id, name) + hid_t id; IN: ID of property list or class to check const char *name; IN: Name of property to query + size_t *size; OUT: Size of property RETURNS - Directly returns the value of the property in the list + Success: non-negative value + Failure: negative value DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. + This routine retrieves the size of a property's value in bytes. Zero- + sized properties are allowed and return a value of 0. This function works + for both property lists and classes. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -void * -H5P_peek_voidp(H5P_genplist_t *plist, const char *name) +herr_t +H5Pget_size(hid_t id, const char *name, size_t *size) { - void * ret_value; /* return value */ - - FUNC_ENTER_NOAPI(H5P_peek_voidp, NULL); - - assert(plist); - assert(name); - - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_peek_voidp() */ + H5P_genclass_t *pclass; /* Property class to query */ + H5P_genplist_t *plist; /* Property list to query */ + herr_t ret_value; /* return value */ - -/*-------------------------------------------------------------------------- - NAME - H5P_peek_size_t - PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. - USAGE - hsize_t H5P_peek_size_t(plist, name) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query - RETURNS - Directly returns the value of the property in the list - DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. + FUNC_ENTER_API(H5Pget_size, FAIL); + H5TRACE3("e", "i*s*z", id, name, size); - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -size_t -H5P_peek_size_t(H5P_genplist_t *plist, const char *name) -{ - size_t ret_value; /* return value */ + /* Check arguments. */ + if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if(size==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property size"); - FUNC_ENTER_NOAPI(H5P_peek_size_t, UFAIL); + if(H5I_GENPROP_LST == H5I_get_type(id)) { + if(NULL == (plist = H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - assert(plist); - assert(name); + /* Check the property size */ + if((ret_value = H5P_get_size_plist(plist, name, size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist"); + } /* end if */ + else + if(H5I_GENPROP_CLS == H5I_get_type(id)) { + if(NULL == (pclass = H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); + /* Check the property size */ + if((ret_value = H5P_get_size_pclass(pclass, name, size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist"); + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_peek_size_t() */ + FUNC_LEAVE_API(ret_value); +} /* H5Pget_size() */ /*-------------------------------------------------------------------------- NAME - H5P_get + H5Pget_class PURPOSE - Internal routine to query the value of a property in a property list. + Routine to query the class of a generic property list USAGE - herr_t H5P_get(plist, name, value) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query - void *value; OUT: Pointer to the buffer for the property value + hid_t H5Pget_class(plist_id) + hid_t plist_id; IN: Property list to query RETURNS - Returns non-negative on success, negative on failure. + Success: ID of class object + Failure: negative DESCRIPTION - Retrieves a copy of the value for a property in a property list. The - property name must exist or this routine will fail. If there is a - 'get' callback routine registered for this property, the copy of the - value of the property will first be passed to that routine and any changes - to the copy of the value will be used when returning the property value - from this routine. - If the 'get' callback routine returns an error, 'value' will not be - modified and this routine will return an error. This routine may not be - called for zero-sized properties. + This routine retrieves the class of a property list. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + Change the name of this function to H5Pget_class (and remove old H5Pget_class) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5P_get(H5P_genplist_t *plist, const char *name, void *value) +hid_t +H5Pget_class(hid_t plist_id) { - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_get, FAIL); - - assert(plist); - assert(name); - assert(value); - - /* Check if the property has been deleted */ - if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); - - /* Find property */ - if((prop=H5SL_search(plist->props,name))!=NULL) { - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size"); + H5P_genplist_t *plist; /* Property list to query */ + H5P_genclass_t *pclass=NULL; /* Property list class */ + hid_t ret_value=FAIL; /* return value */ - /* Make a copy of the value and pass to 'get' callback */ - if(prop->get!=NULL) { - void *tmp_value; /* Temporary value for property */ + FUNC_ENTER_API(H5Pget_class, FAIL); + H5TRACE1("i", "i", plist_id); - /* Make a copy of the current value, in case the callback fails */ - if (NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); - HDmemcpy(tmp_value,prop->value,prop->size); + /* Check arguments. */ + if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - /* Call user's callback */ - if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value"); + /* Retrieve the property list class */ + if((pclass = H5P_get_class(plist)) == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list"); - /* Copy new [possibly unchanged] value into return value */ - HDmemcpy(value,tmp_value,prop->size); + /* Increment the outstanding references to the class object */ + if(H5P_access_class(pclass, H5P_MOD_INC_REF) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count"); - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'get' callback, just copy value */ - else - HDmemcpy(value,prop->value,prop->size); - } /* end if */ - else { - /* - * Check if we should get class properties (up through list of parent classes also), - * & make property 'get' callback. - */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Find the property in the class */ - if((prop=H5SL_search(tclass->props,name))!=NULL) { - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size"); - - /* Call the 'get' callback, if there is one */ - if(prop->get!=NULL) { - void *tmp_value; /* Temporary value for property */ - - /* Make a copy of the current value, in case the callback fails */ - if (NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); - HDmemcpy(tmp_value,prop->value,prop->size); - - /* Call user's callback */ - if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value)<0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); - } /* end if */ - - if(HDmemcmp(tmp_value,prop->value,prop->size)) { - H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */ - - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); - - /* Copy new value into property value */ - HDmemcpy(pcopy->value,tmp_value,prop->size); - - /* Insert the changed property into the property list */ - if(H5P_add_prop(plist->props,pcopy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); - } /* end if */ - - /* Copy new [possibly unchanged] value into return value */ - HDmemcpy(value,tmp_value,prop->size); - - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'get' callback, just copy value */ - else - HDmemcpy(value,prop->value,prop->size); - - /* Leave */ - HGOTO_DONE(SUCCEED); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* If we get this far, then it wasn't in the list of changed properties, - * nor in the properties in the class hierarchy, indicate an error - */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); - } /* end else */ + /* Get an atom for the class */ + if((ret_value = H5I_register(H5I_GENPROP_CLS, pclass)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_get() */ + if(ret_value<0 && pclass) + H5P_close_class(pclass); + + FUNC_LEAVE_API(ret_value); +} /* H5Pget_class() */ /*-------------------------------------------------------------------------- NAME - H5Pget + H5Pget_nprops PURPOSE - Routine to query the value of a property in a property list. + Routine to query the size of a property in a property list or class. USAGE - herr_t H5Pget(plist_id, name, value) - hid_t plist_id; IN: Property list to check - const char *name; IN: Name of property to query - void *value; OUT: Pointer to the buffer for the property value + herr_t H5Pget_nprops(id, nprops) + hid_t id; IN: ID of Property list or class to check + size_t *nprops; OUT: Number of properties in the property object RETURNS - Returns non-negative on success, negative on failure. + Success: non-negative value + Failure: negative value DESCRIPTION - Retrieves a copy of the value for a property in a property list. The - property name must exist or this routine will fail. If there is a - 'get' callback routine registered for this property, the copy of the - value of the property will first be passed to that routine and any changes - to the copy of the value will be used when returning the property value - from this routine. - If the 'get' callback routine returns an error, 'value' will not be - modified and this routine will return an error. This routine may not be - called for zero-sized properties. + This routine retrieves the number of properties in a property list or + class. If a property class ID is given, the number of registered properties + in the class is returned in NPROPS. If a property list ID is given, the + current number of properties in the list is returned in NPROPS. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS @@ -4771,382 +909,331 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5Pget(hid_t plist_id, const char *name, void *value) +H5Pget_nprops(hid_t id, size_t *nprops) { - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ + H5P_genplist_t *plist; /* Property list to query */ + H5P_genclass_t *pclass; /* Property class to query */ + herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER_API(H5Pget, FAIL); - H5TRACE3("e", "i*s*x", plist_id, name, value); + FUNC_ENTER_API(H5Pget_nprops, FAIL); + H5TRACE2("e", "i*z", id, nprops); /* Check arguments. */ - if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - if (value==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value"); + if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); + if(nprops==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property nprops pointer"); - /* Go get the value */ - if(H5P_get(plist,name,value)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value"); + if(H5I_GENPROP_LST == H5I_get_type(id)) { + if(NULL == (plist = H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if(H5P_get_nprops_plist(plist, nprops) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in plist"); + } /* end if */ + else + if(H5I_GENPROP_CLS == H5I_get_type(id)) { + if(NULL == (pclass = H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); + if(H5P_get_nprops_pclass(pclass, nprops, FALSE) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query # of properties in pclass"); + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); done: FUNC_LEAVE_API(ret_value); -} /* H5Pget() */ +} /* H5Pget_nprops() */ /*-------------------------------------------------------------------------- NAME - H5P_remove + H5Pequal PURPOSE - Internal routine to remove a property from a property list. + Routine to query whether two property lists or two property classes are equal USAGE - herr_t H5P_remove(plist, name) - H5P_genplist_t *plist; IN: Property list to modify - const char *name; IN: Name of property to remove + htri_t H5Pequal(id1, id2) + hid_t id1; IN: Property list or class ID to compare + hid_t id2; IN: Property list or class ID to compare RETURNS - Returns non-negative on success, negative on failure. + Success: TRUE if equal, FALSE if unequal + Failure: negative DESCRIPTION - Removes a property from a property list. Both properties which were - in existance when the property list was created (i.e. properties registered - with H5Pregister) and properties added to the list after it was created - (i.e. added with H5Pinsert) may be removed from a property list. - Properties do not need to be removed a property list before the list itself - is closed, they will be released automatically when H5Pclose is called. - The 'close' callback for this property is called before the property is - release, if the callback exists. + Determines whether two property lists or two property classes are equal. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) +htri_t +H5Pequal(hid_t id1, hid_t id2) { - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genprop_t *prop; /* Temporary property pointer */ - char *del_name; /* Pointer to deleted name */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_remove,FAIL); - - assert(plist); - assert(name); - - /* Indicate that the property isn't in the list if it has been deleted already */ - if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); - - /* Get the property node from the changed property skip list */ - if((prop=H5SL_search(plist->props,name))!=NULL) { - /* Pass value to 'close' callback, if it exists */ - if(prop->del!=NULL) { - /* Call user's callback */ - if((*(prop->del))(plist_id,name,prop->size,prop->value)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value"); - } /* end if */ - - /* Duplicate string for insertion into new deleted property skip list */ - if((del_name=H5MM_xstrdup(name))==NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); - - /* Insert property name into deleted list */ - if(H5SL_insert(plist->del,del_name,del_name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); + void *obj1, *obj2; /* Property objects to compare */ + htri_t ret_value = FALSE; /* return value */ - /* Remove the property from the skip list */ - if(H5SL_remove(plist->props,prop->name)==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list"); + FUNC_ENTER_API(H5Pequal, FAIL) + H5TRACE2("t", "ii", id1, id2); - /* Free the property, ignoring return value, nothing we can do */ - H5P_free_prop(prop); + /* Check arguments. */ + if((H5I_GENPROP_LST != H5I_get_type(id1) && H5I_GENPROP_CLS != H5I_get_type(id1)) + || (H5I_GENPROP_LST != H5I_get_type(id2) && H5I_GENPROP_CLS != H5I_get_type(id2))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects") + if(H5I_get_type(id1) != H5I_get_type(id2)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects") + if(NULL == (obj1 = H5I_object(id1)) || NULL == (obj2 = H5I_object(id2))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist") - /* Decrement the number of properties in list */ - plist->nprops--; + /* Compare property lists */ + if(H5I_GENPROP_LST == H5I_get_type(id1)) { + if(H5P_cmp_plist(obj1, obj2) == 0) + ret_value = TRUE; } /* end if */ - /* Walk through all the properties in the class hierarchy, looking for the property */ + /* Must be property classes */ else { - /* - * Check if we should delete class properties (up through list of parent classes also), - * & make property 'delete' callback. - */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Find the property in the class */ - if((prop=H5P_find_prop_pclass(tclass,name))!=NULL) { - /* Pass value to 'del' callback, if it exists */ - if(prop->del!=NULL) { - void *tmp_value; /* Temporary value buffer */ - - /* Allocate space for a temporary copy of the property value */ - if (NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); - HDmemcpy(tmp_value,prop->value,prop->size); - - /* Call user's callback */ - if((*(prop->del))(plist_id,name,prop->size,tmp_value)<0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value"); - } /* end if */ - - /* Release the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - - /* Duplicate string for insertion into new deleted property skip list */ - if((del_name=H5MM_xstrdup(name))==NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); - - /* Insert property name into deleted list */ - if(H5SL_insert(plist->del,del_name,del_name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); - - /* Decrement the number of properties in list */ - plist->nprops--; - - /* Leave */ - HGOTO_DONE(SUCCEED); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* If we get this far, then it wasn't in the list of changed properties, - * nor in the properties in the class hierarchy, indicate an error - */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + if(H5P_cmp_class(obj1, obj2) == 0) + ret_value = TRUE; } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_remove() */ + FUNC_LEAVE_API(ret_value) +} /* H5Pequal() */ /*-------------------------------------------------------------------------- NAME - H5Premove + H5Pisa_class PURPOSE - Routine to remove a property from a property list. + Routine to query whether a property list is a certain class USAGE - herr_t H5Premove(plist_id, name) - hid_t plist_id; IN: Property list to modify - const char *name; IN: Name of property to remove + hid_t H5Pisa_class(plist_id, pclass_id) + hid_t plist_id; IN: Property list to query + hid_t pclass_id; IN: Property class to query RETURNS - Returns non-negative on success, negative on failure. + Success: TRUE (1) or FALSE (0) + Failure: negative DESCRIPTION - Removes a property from a property list. Both properties which were - in existance when the property list was created (i.e. properties registered - with H5Pregister) and properties added to the list after it was created - (i.e. added with H5Pinsert) may be removed from a property list. - Properties do not need to be removed a property list before the list itself - is closed, they will be released automatically when H5Pclose is called. - The 'close' callback for this property is called before the property is - release, if the callback exists. + This routine queries whether a property list is a member of the property + list class. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + What about returning a value indicating that the property class is further + up the class hierarchy? EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5Premove(hid_t plist_id, const char *name) +htri_t +H5Pisa_class(hid_t plist_id, hid_t pclass_id) { - H5P_genplist_t *plist; /* Property list to modify */ - herr_t ret_value; /* return value */ + htri_t ret_value; /* return value */ - FUNC_ENTER_API(H5Premove, FAIL); - H5TRACE2("e", "i*s", plist_id, name); + FUNC_ENTER_API(H5Pisa_class, FAIL); + H5TRACE2("t", "ii", plist_id, pclass_id); /* Check arguments. */ - if (NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + if(H5I_GENPROP_LST != H5I_get_type(plist_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if(H5I_GENPROP_CLS != H5I_get_type(pclass_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); - /* Create the new property list class */ - if ((ret_value=H5P_remove(plist_id,plist,name))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + /* Compare the property list's class against the other class */ + if((ret_value = H5P_isa_class(plist_id, pclass_id)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes"); done: FUNC_LEAVE_API(ret_value); -} /* H5Premove() */ +} /* H5Pisa_class() */ /*-------------------------------------------------------------------------- NAME - H5P_copy_prop_plist + H5Piterate PURPOSE - Internal routine to copy a property from one list to another + Routine to iterate over the properties in a property list or class USAGE - herr_t H5P_copy_prop_plist(dst_plist, src_plist, name) - hid_t dst_id; IN: ID of destination property list or class - hid_t src_id; IN: ID of source property list or class - const char *name; IN: Name of property to copy + int H5Piterate(pclass_id, idx, iter_func, iter_data) + hid_t id; IN: ID of property object to iterate over + int *idx; IN/OUT: Index of the property to begin with + H5P_iterate_t iter_func; IN: Function pointer to function to be + called with each property iterated over. + void *iter_data; IN/OUT: Pointer to iteration data from user RETURNS - Success: non-negative value. - Failure: negative value. + Success: Returns the return value of the last call to ITER_FUNC if it was + non-zero, or zero if all properties have been processed. + Failure: negative value DESCRIPTION - Copies a property from one property list to another. + This routine iterates over the properties in the property object specified +with ID. The properties in both property lists and classes may be iterated +over with this function. For each property in the object, the ITER_DATA and +some additional information, specified below, are passed to the ITER_FUNC +function. The iteration begins with the IDX property in the object and the +next element to be processed by the operator is returned in IDX. If IDX is +NULL, then the iterator starts at the first property; since no stopping point +is returned in this case, the iterator cannot be restarted if one of the calls +to its operator returns non-zero. The IDX value is 0-based (ie. to start at +the "first" property, the IDX value should be 0). - If a property is copied from one list to another, the property will be - first deleted from the destination list (generating a call to the 'close' - callback for the property, if one exists) and then the property is copied - from the source list to the destination list (generating a call to the - 'copy' callback for the property, if one exists). +The prototype for H5P_iterate_t is: + typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); +The operation receives the property list or class identifier for the object +being iterated over, ID, the name of the current property within the object, +NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA. + +The return values from an operator are: + Zero causes the iterator to continue, returning zero when all properties + have been processed. + Positive causes the iterator to immediately return that positive value, + indicating short-circuit success. The iterator can be restarted at the + index of the next property. + Negative causes the iterator to immediately return that value, indicating + failure. The iterator can be restarted at the index of the next + property. - If the property does not exist in the destination list, this call is - equivalent to calling H5Pinsert and the 'create' callback will be called - (if such a callback exists for the property). +H5Piterate assumes that the properties in the object identified by ID remains +unchanged through the iteration. If the membership changes during the +iteration, the function's behavior is undefined. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) +int +H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data) { - H5P_genplist_t *dst_plist; /* Pointer to destination property list */ - H5P_genplist_t *src_plist; /* Pointer to source property list */ - H5P_genprop_t *prop; /* Temporary property pointer */ - H5P_genprop_t *new_prop=NULL; /* Pointer to new property */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_plist); - - assert(name); - - /* Get the objects to operate on */ - if(NULL == (src_plist = H5I_object(src_id)) || NULL == (dst_plist = H5I_object(dst_id))) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist"); - - /* If the property exists in the destination alread */ - if(H5P_find_prop_plist(dst_plist,name)!=NULL) { - /* Delete the property from the destination list, calling the 'close' callback if necessary */ - if(H5P_remove(dst_id,dst_plist,name)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + int fake_idx = 0; /* Index when user doesn't provide one */ + int ret_value; /* return value */ - /* Get the pointer to the source property */ - prop=H5P_find_prop_plist(src_plist,name); + FUNC_ENTER_API(H5Piterate, FAIL); + H5TRACE4("Is", "i*Isx*x", id, idx, iter_func, iter_data); - /* Make a copy of the source property */ - if((new_prop=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + /* Check arguments. */ + if(H5I_GENPROP_LST != H5I_get_type(id) && H5I_GENPROP_CLS != H5I_get_type(id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); + if(iter_func == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration callback"); - /* Call property copy callback, if it exists */ - if(new_prop->copy) { - if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + if(H5I_GENPROP_LST == H5I_get_type(id)) { + /* Iterate over a property list */ + if((ret_value = H5P_iterate_plist(id, (idx ? idx : &fake_idx), iter_func, iter_data)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over list"); + } /* end if */ + else + if(H5I_GENPROP_CLS == H5I_get_type(id)) { + /* Iterate over a property class */ + if((ret_value = H5P_iterate_pclass(id, (idx ? idx : &fake_idx), iter_func, iter_data)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to iterate over class"); } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property object"); - /* Insert the initialized property into the property list */ - if(H5P_add_prop(dst_plist->props,new_prop)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list"); - - /* Increment the number of properties in list */ - dst_plist->nprops++; - } /* end if */ - /* If not, get the information required to do an H5Pinsert with the property into the destination list */ - else { - /* Get the pointer to the source property */ - prop=H5P_find_prop_plist(src_plist,name); +done: + FUNC_LEAVE_API(ret_value); +} /* H5Piterate() */ - /* Create property object from parameters */ - if((new_prop=H5P_create_prop(prop->name,prop->size,H5P_PROP_WITHIN_LIST,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); + +/*-------------------------------------------------------------------------- + NAME + H5Pget + PURPOSE + Routine to query the value of a property in a property list. + USAGE + herr_t H5Pget(plist_id, name, value) + hid_t plist_id; IN: Property list to check + const char *name; IN: Name of property to query + void *value; OUT: Pointer to the buffer for the property value + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Retrieves a copy of the value for a property in a property list. The + property name must exist or this routine will fail. If there is a + 'get' callback routine registered for this property, the copy of the + value of the property will first be passed to that routine and any changes + to the copy of the value will be used when returning the property value + from this routine. + If the 'get' callback routine returns an error, 'value' will not be + modified and this routine will return an error. This routine may not be + called for zero-sized properties. - /* Call property creation callback, if it exists */ - if(new_prop->create) { - if((new_prop->create)(new_prop->name,new_prop->size,new_prop->value)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); - } /* end if */ + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5Pget(hid_t plist_id, const char *name, void *value) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value=SUCCEED; /* return value */ - /* Insert property into property list class */ - if(H5P_add_prop(dst_plist->props,new_prop)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + FUNC_ENTER_API(H5Pget, FAIL); + H5TRACE3("e", "i*s*x", plist_id, name, value); - /* Increment property count for class */ - dst_plist->nprops++; + /* Check arguments. */ + if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if(value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value"); - } /* end else */ + /* Go get the value */ + if(H5P_get(plist,name,value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value"); done: - /* Cleanup, if necessary */ - if(ret_value<0) { - if(new_prop!=NULL) - H5P_free_prop(new_prop); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_copy_prop_plist() */ + FUNC_LEAVE_API(ret_value); +} /* H5Pget() */ /*-------------------------------------------------------------------------- NAME - H5P_copy_prop_pclass + H5Premove PURPOSE - Internal routine to copy a property from one class to another + Routine to remove a property from a property list. USAGE - herr_t H5P_copy_prop_pclass(dst_pclass, src_pclass, name) - H5P_genclass_t *dst_pclass; IN: Pointer to destination class - H5P_genclass_t *src_pclass; IN: Pointer to source class - const char *name; IN: Name of property to copy + herr_t H5Premove(plist_id, name) + hid_t plist_id; IN: Property list to modify + const char *name; IN: Name of property to remove RETURNS - Success: non-negative value. - Failure: negative value. + Returns non-negative on success, negative on failure. DESCRIPTION - Copies a property from one property class to another. - - If a property is copied from one class to another, all the property - information will be first deleted from the destination class and then the - property information will be copied from the source class into the - destination class. - - If the property does not exist in the destination class or list, this call - is equivalent to calling H5Pregister. + Removes a property from a property list. Both properties which were + in existance when the property list was created (i.e. properties registered + with H5Pregister2) and properties added to the list after it was created + (i.e. added with H5Pinsert) may be removed from a property list. + Properties do not need to be removed a property list before the list itself + is closed, they will be released automatically when H5Pclose is called. + The 'close' callback for this property is called before the property is + release, if the callback exists. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, const char *name) +herr_t +H5Premove(hid_t plist_id, const char *name) { - H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_pclass); - - assert(dst_pclass); - assert(src_pclass); - assert(name); + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value; /* return value */ - /* If the property exists in the destination already */ - if(H5P_exist_pclass(dst_pclass,name)) { - /* Delete the old property from the destination class */ - if(H5P_unregister(dst_pclass,name)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); - } /* end if */ + FUNC_ENTER_API(H5Premove, FAIL); + H5TRACE2("e", "i*s", plist_id, name); - /* Get the property from the source */ - if((prop=H5P_find_prop_pclass(src_pclass,name))==NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to locate property"); + /* Check arguments. */ + if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); - /* Register the property into the destination */ - if(H5P_register(dst_pclass,name,prop->size,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close)<0) + /* Create the new property list class */ + if((ret_value = H5P_remove(plist_id,plist,name)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); done: - /* Cleanup, if necessary */ - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_copy_prop_pclass() */ + FUNC_LEAVE_API(ret_value); +} /* H5Premove() */ /*-------------------------------------------------------------------------- @@ -5177,7 +1264,7 @@ done: 'copy' callback for the property, if one exists). If the property does not exist in the destination class or list, this call - is equivalent to calling H5Pregister or H5Pinsert (for a class or list, as + is equivalent to calling H5Pregister2 or H5Pinsert (for a class or list, as appropriate) and the 'create' callback will be called in the case of the property being copied into a list (if such a callback exists for the property). @@ -5197,24 +1284,24 @@ H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name) H5TRACE3("e", "ii*s", dst_id, src_id, name); /* Check arguments. */ - if ((H5I_GENPROP_LST != H5I_get_type(src_id) && H5I_GENPROP_CLS != H5I_get_type(src_id)) + if((H5I_GENPROP_LST != H5I_get_type(src_id) && H5I_GENPROP_CLS != H5I_get_type(src_id)) || (H5I_GENPROP_LST != H5I_get_type(dst_id) && H5I_GENPROP_CLS != H5I_get_type(dst_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property objects"); - if (H5I_get_type(src_id) != H5I_get_type(dst_id)) + if(H5I_get_type(src_id) != H5I_get_type(dst_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not the same kind of property objects"); - if (!name || !*name) + if(!name || !*name) HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given"); if(NULL == (src_obj = H5I_object(src_id)) || NULL == (dst_obj = H5I_object(dst_id))) HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist"); /* Compare property lists */ if(H5I_GENPROP_LST == H5I_get_type(src_id)) { - if(H5P_copy_prop_plist(dst_id,src_id,name)<0) + if(H5P_copy_prop_plist(dst_id, src_id, name) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between lists"); } /* end if */ /* Must be property classes */ else { - if(H5P_copy_prop_pclass(dst_obj,src_obj,name)<0) + if(H5P_copy_prop_pclass(dst_obj, src_obj, name) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property between classes"); } /* end else */ @@ -5225,60 +1312,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_unregister - PURPOSE - Internal routine to remove a property from a property list class. - USAGE - herr_t H5P_unregister(pclass, name) - H5P_genclass_t *pclass; IN: Property list class to modify - const char *name; IN: Name of property to remove - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Removes a property from a property list class. Future property lists - created of that class will not contain this property. Existing property - lists containing this property are not affected. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5P_unregister(H5P_genclass_t *pclass, const char *name) -{ - H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_unregister); - - assert(pclass); - assert(name); - - /* Get the property node from the skip list */ - if((prop=H5SL_search(pclass->props,name))==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); - - /* Remove the property from the skip list */ - if(H5SL_remove(pclass->props,prop->name)==NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list"); - - /* Free the property, ignoring return value, nothing we can do */ - H5P_free_prop(prop); - - /* Decrement the number of registered properties in class */ - pclass->nprops--; - - /* Update the revision for the class */ - pclass->revision = H5P_GET_NEXT_REV; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_unregister() */ - - -/*-------------------------------------------------------------------------- - NAME H5Punregister PURPOSE Routine to remove a property from a property list class. @@ -5308,13 +1341,13 @@ H5Punregister(hid_t pclass_id, const char *name) H5TRACE2("e", "i*s", pclass_id, name); /* Check arguments. */ - if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) + if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); - if (!name || !*name) + if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); /* Remove the property list from class */ - if ((ret_value=H5P_unregister(pclass,name))<0) + if((ret_value = H5P_unregister(pclass, name)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to remove property from class"); done: @@ -5324,168 +1357,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_close - PURPOSE - Internal routine to close a property list. - USAGE - herr_t H5P_close(plist) - H5P_genplist_t *plist; IN: Property list to close - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Closes a property list. If a 'close' callback exists for the property - list class, it is called before the property list is destroyed. If 'close' - callbacks exist for any individual properties in the property list, they are - called after the class 'close' callback. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - The property list class 'close' callback routine is not called from - here, it must have been check for and called properly prior to this routine - being called - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_close(void *_plist) -{ - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genplist_t *plist=(H5P_genplist_t *)_plist; - H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */ - size_t nseen; /* Number of items 'seen' */ - hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */ - size_t ndel; /* Number of items deleted */ - H5SL_node_t *curr_node; /* Current node in skip list */ - H5P_genprop_t *tmp; /* Temporary pointer to properties */ - unsigned make_cb=0; /* Operator data for property free callback */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_close); - - assert(plist); - - /* Make call to property list class close callback, if needed */ - if(plist->class_init!=0 && plist->pclass->close_func!=NULL) { - /* Call user's "close" callback function, ignoring return value */ - (plist->pclass->close_func)(plist->plist_id,plist->pclass->close_data); - } /* end if */ - - /* Create the skip list to hold names of properties already seen - * (This prevents a property in the class hierarchy from having it's - * 'close' callback called, if a property in the class hierarchy has - * already been seen) - */ - if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); - nseen = 0; - - /* Walk through the changed properties in the list */ - if(H5SL_count(plist->props)>0) { - curr_node=H5SL_first(plist->props); - while(curr_node!=NULL) { - /* Get pointer to property from node */ - tmp=H5SL_item(curr_node); - - /* Call property close callback, if it exists */ - if(tmp->close) { - /* Call the 'close' callback */ - (tmp->close)(tmp->name,tmp->size,tmp->value); - } /* end if */ - - /* Add property name to "seen" list */ - if(H5SL_insert(seen,tmp->name,tmp->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); - nseen++; - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Determine number of deleted items from property list */ - ndel=H5SL_count(plist->del); - - /* - * Check if we should remove class properties (up through list of parent classes also), - * initialize each with default value & make property 'remove' callback. - */ - tclass=plist->pclass; - has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0); - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Walk through the properties in the class */ - curr_node=H5SL_first(tclass->props); - while(curr_node!=NULL) { - /* Get pointer to property from node */ - tmp=H5SL_item(curr_node); - - /* Only "delete" properties we haven't seen before - * and that haven't already been deleted - */ - if((nseen==0 || H5SL_search(seen,tmp->name)==NULL) && - (ndel==0 || H5SL_search(plist->del,tmp->name)==NULL)) { - - /* Call property close callback, if it exists */ - if(tmp->close) { - void *tmp_value; /* Temporary value buffer */ - - /* Allocate space for a temporary copy of the property value */ - if (NULL==(tmp_value=H5MM_malloc(tmp->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); - HDmemcpy(tmp_value,tmp->value,tmp->size); - - /* Call the 'close' callback */ - (tmp->close)(tmp->name,tmp->size,tmp_value); - - /* Release the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - - /* Add property name to "seen" list, if we have other classes to work on */ - if(has_parent_class) { - if(H5SL_insert(seen,tmp->name,tmp->name)<0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); - nseen++; - } /* end if */ - } /* end if */ - - /* Get the next property node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* Decrement class's dependant property list value! */ - if(H5P_access_class(plist->pclass,H5P_MOD_DEC_LST)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count"); - - /* Free the list of 'seen' properties */ - H5SL_close(seen); - seen=NULL; - - /* Free the list of deleted property names */ - H5SL_destroy(plist->del,H5P_free_del_name_cb,NULL); - - /* Free the properties */ - H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb); - - /* Destroy property list object */ - H5FL_FREE(H5P_genplist_t,plist); - -done: - /* Release the skip list of 'seen' properties */ - if(seen!=NULL) - H5SL_close(seen); - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_close() */ - - -/*-------------------------------------------------------------------------- - NAME H5Pclose PURPOSE Routine to close a property list. @@ -5513,15 +1384,15 @@ H5Pclose(hid_t plist_id) FUNC_ENTER_API(H5Pclose, FAIL); H5TRACE1("e", "i", plist_id); - if (plist_id==H5P_DEFAULT) + if(plist_id==H5P_DEFAULT) HGOTO_DONE(SUCCEED); /* Check arguments. */ - if (H5I_GENPROP_LST != H5I_get_type(plist_id)) + if(H5I_GENPROP_LST != H5I_get_type(plist_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); /* Close the property list */ - if (H5I_dec_ref(plist_id) < 0) + if(H5I_dec_ref(plist_id) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close"); done: @@ -5531,43 +1402,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_get_class_name - PURPOSE - Internal routine to query the name of a generic property list class - USAGE - char *H5P_get_class_name(pclass) - H5P_genclass_t *pclass; IN: Property list class to check - RETURNS - Success: Pointer to a malloc'ed string containing the class name - Failure: NULL - DESCRIPTION - This routine retrieves the name of a generic property list class. - The pointer to the name must be free'd by the user for successful calls. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -char * -H5P_get_class_name(H5P_genclass_t *pclass) -{ - char *ret_value; /* return value */ - - FUNC_ENTER_NOAPI(H5P_get_class_name, NULL); - - assert(pclass); - - /* Get class name */ - ret_value=H5MM_xstrdup(pclass->name); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_get_class_name() */ - - -/*-------------------------------------------------------------------------- - NAME H5Pget_class_name PURPOSE Routine to query the name of a generic property list class @@ -5595,11 +1429,11 @@ H5Pget_class_name(hid_t pclass_id) FUNC_ENTER_API(H5Pget_class_name, NULL); /* Check arguments. */ - if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) + if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property class"); /* Get the property list class name */ - if ((ret_value=H5P_get_class_name(pclass))==NULL) + if((ret_value = H5P_get_class_name(pclass)) == NULL) HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "unable to query name of class"); done: @@ -5609,186 +1443,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_get_class_path - PURPOSE - Internal routine to query the full path of a generic property list class - USAGE - char *H5P_get_class_name(pclass) - H5P_genclass_t *pclass; IN: Property list class to check - RETURNS - Success: Pointer to a malloc'ed string containing the full path of class - Failure: NULL - DESCRIPTION - This routine retrieves the full path name of a generic property list - class, starting with the root of the class hierarchy. - The pointer to the name must be free'd by the user for successful calls. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -char * -H5P_get_class_path(H5P_genclass_t *pclass) -{ - char *par_path; /* Parent class's full path */ - size_t par_path_len;/* Parent class's full path's length */ - size_t my_path_len; /* This class's name's length */ - char *ret_value; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_get_class_path); - - assert(pclass); - - /* Recursively build the full path */ - if(pclass->parent!=NULL) { - /* Get the parent class's path */ - par_path=H5P_get_class_path(pclass->parent); - if(par_path!=NULL) { - /* Get the string lengths we need to allocate space */ - par_path_len=HDstrlen(par_path); - my_path_len=HDstrlen(pclass->name); - - /* Allocate enough space for the parent class's path, plus the '/' - * separator, this class's name and the string terminator - */ - if(NULL==(ret_value=H5MM_malloc(par_path_len+1+my_path_len+1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for class name"); - - /* Build the full path for this class */ - HDstrcpy(ret_value,par_path); - HDstrcat(ret_value,"/"); - HDstrcat(ret_value,pclass->name); - - /* Free the parent class's path */ - H5MM_xfree(par_path); - } /* end if */ - else - ret_value=H5MM_xstrdup(pclass->name); - } /* end if */ - else - ret_value=H5MM_xstrdup(pclass->name); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_get_class_path() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_open_class_path - PURPOSE - Internal routine to open [a copy of] a class with its full path name - USAGE - H5P_genclass_t *H5P_open_class_path(path) - const char *path; IN: Full path name of class to open [copy of] - RETURNS - Success: Pointer to a generic property class object - Failure: NULL - DESCRIPTION - This routine opens [a copy] of the class indicated by the full path. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -H5P_genclass_t * -H5P_open_class_path(const char *path) -{ - char *tmp_path=NULL; /* Temporary copy of the path */ - char *curr_name; /* Pointer to current component of path name */ - char *delimit; /* Pointer to path delimiter during traversal */ - H5P_genclass_t *curr_class; /* Pointer to class during path traversal */ - H5P_genclass_t *ret_value; /* Return value */ - H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_open_class_path); - - assert(path); - - /* Duplicate the path to use */ - tmp_path=H5MM_xstrdup(path); - assert(tmp_path); - - /* Find the generic property class with this full path */ - curr_name=tmp_path; - curr_class=NULL; - while((delimit=HDstrchr(curr_name,'/'))!=NULL) { - /* Change the delimiter to terminate the string */ - *delimit='\0'; - - /* Set up the search structure */ - check_info.parent=curr_class; - check_info.name=curr_name; - - /* Find the class with this name & parent by iterating over the open classes */ - if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class"); - - /* Advance the pointer in the path to the start of the next component */ - curr_name=delimit+1; - } /* end while */ - - /* Should be pointing to the last component in the path name now... */ - - /* Set up the search structure */ - check_info.parent=curr_class; - check_info.name=curr_name; - - /* Find the class with this name & parent by iterating over the open classes */ - if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class"); - - /* Copy it */ - if((ret_value=H5P_copy_pclass(curr_class))==NULL) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class"); - -done: - /* Free the duplicated path */ - H5MM_xfree(tmp_path); - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_open_class_path() */ - - -/*-------------------------------------------------------------------------- - NAME - H5P_get_class_parent - PURPOSE - Internal routine to query the parent class of a generic property class - USAGE - H5P_genclass_t *H5P_get_class_parent(pclass) - H5P_genclass_t *pclass; IN: Property class to check - RETURNS - Success: Pointer to the parent class of a property class - Failure: NULL - DESCRIPTION - This routine retrieves a pointer to the parent class for a property class. - - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5P_genclass_t * -H5P_get_class_parent(H5P_genclass_t *pclass) -{ - H5P_genclass_t *ret_value; /* return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class_parent); - - assert(pclass); - - /* Get property size */ - ret_value=pclass->parent; - - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_get_class_parent() */ - - -/*-------------------------------------------------------------------------- - NAME H5Pget_class_parent PURPOSE routine to query the parent class of a generic property class @@ -5817,23 +1471,23 @@ H5Pget_class_parent(hid_t pclass_id) H5TRACE1("i", "i", pclass_id); /* Check arguments. */ - if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) + if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); /* Retrieve the property class's parent */ - if ((parent=H5P_get_class_parent(pclass))==NULL) + if((parent = H5P_get_class_parent(pclass)) == NULL) HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to query class of property list"); /* Increment the outstanding references to the class object */ - if(H5P_access_class(parent,H5P_MOD_INC_REF)<0) + if(H5P_access_class(parent, H5P_MOD_INC_REF) < 0) HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ID ref count"); /* Get an atom for the class */ - if ((ret_value = H5I_register(H5I_GENPROP_CLS, parent))<0) + if((ret_value = H5I_register(H5I_GENPROP_CLS, parent)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); done: - if (ret_value<0 && parent) + if(ret_value<0 && parent) H5P_close_class(parent); FUNC_LEAVE_API(ret_value); @@ -5842,42 +1496,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_close_class - PURPOSE - Internal routine to close a property list class. - USAGE - herr_t H5P_close_class(class) - H5P_genclass_t *class; IN: Property list class to close - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Releases memory and de-attach a class from the property list class hierarchy. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5P_close_class(void *_pclass) -{ - H5P_genclass_t *pclass=(H5P_genclass_t *)_pclass; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5P_close_class); - - assert(pclass); - - /* Decrement the reference count & check if the object should go away */ - if(H5P_access_class(pclass,H5P_MOD_DEC_REF)<0) - HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, FAIL, "Can't decrement ID ref count"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* H5P_close_class() */ - - -/*-------------------------------------------------------------------------- - NAME H5Pclose_class PURPOSE Close a property list class. @@ -5903,11 +1521,11 @@ H5Pclose_class(hid_t cls_id) H5TRACE1("e", "i", cls_id); /* Check arguments */ - if (H5I_GENPROP_CLS != H5I_get_type(cls_id)) + if(H5I_GENPROP_CLS != H5I_get_type(cls_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); /* Close the property list class */ - if (H5I_dec_ref(cls_id) < 0) + if(H5I_dec_ref(cls_id) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close"); done: diff --git a/src/H5Pdeprec.c b/src/H5Pdeprec.c new file mode 100644 index 0000000..924e68f --- /dev/null +++ b/src/H5Pdeprec.c @@ -0,0 +1,276 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Pdeprec.c + * October 11 2007 + * Quincey Koziol + * + * Purpose: Deprecated functions from the H5P interface. These + * functions are here for compatibility purposes and may be + * removed in the future. Applications should switch to the + * newer APIs. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5P_PACKAGE /*suppress error about including H5Ppkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5P_init_deprec_interface + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Ppkg.h" /* Property lists */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*-------------------------------------------------------------------------- +NAME + H5P_init_deprec_interface -- Initialize interface-specific information +USAGE + herr_t H5P_init_deprec_interface() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5P_init() currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5P_init_deprec_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_init_deprec_interface) + + FUNC_LEAVE_NOAPI(H5P_init()) +} /* H5P_init_deprec_interface() */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/*-------------------------------------------------------------------------- + NAME + H5Pregister1 + PURPOSE + Routine to register a new property in a property list class. + USAGE + herr_t H5Pregister1(class, name, size, default, prp_create, prp_set, prp_get, prp_close) + hid_t class; IN: Property list class to close + const char *name; IN: Name of property to register + size_t size; IN: Size of property in bytes + void *def_value; IN: Pointer to buffer containing default value + for property in newly created property lists + H5P_prp_create_func_t prp_create; IN: Function pointer to property + creation callback + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback + H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Registers a new property with a property list class. The property will + exist in all property list objects of that class after this routine is + finished. The name of the property must not already exist. The default + property value must be provided and all new property lists created with this + property will have the property value set to the default provided. Any of + the callback routines may be set to NULL if they are not needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'default' pointer for a + zero-sized property may be set to NULL. The property 'create' & 'close' + callbacks are called for zero-sized properties, but the 'set' and 'get' + callbacks are never called. + + The 'create' callback is called when a new property list with this + property is being created. H5P_prp_create_func_t is defined as: + typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, + size_t size, void *initial_value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being created. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *initial_value; IN/OUT: The initial value for the property being created. + (The 'default' value passed to H5Pregister1) + The 'create' routine may modify the value to be set and those changes will + be stored as the initial value of the property. If the 'create' routine + returns a negative value, the new property value is not copied into the + property and the property list creation routine returns an error value. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'delete' callback is called when a property is deleted from a + property list. H5P_prp_del_func_t is defined as: + typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list the property is deleted from. + const char *name; IN: The name of the property being deleted. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value of the property being deleted. + The 'delete' routine may modify the value passed in, but the value is not + used by the library when the 'delete' routine returns. If the + 'delete' routine returns a negative value, the property list deletion + routine returns an error value but the property is still deleted. + + The 'copy' callback is called when a property list with this + property is copied. H5P_prp_copy_func_t is defined as: + typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being copied. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being copied. + The 'copy' routine may modify the value to be copied and those changes will be + stored as the value of the property. If the 'copy' routine returns a + negative value, the new property value is not copied into the property and + the property list copy routine returns an error value. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5Pregister1(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_close_func_t prp_close) +{ + H5P_genclass_t *pclass; /* Property list class to modify */ + herr_t ret_value; /* return value */ + + FUNC_ENTER_API(H5Pregister1, FAIL); + H5TRACE10("e","iszxxxxxxx",cls_id,name,size,def_value,prp_create,prp_set, + prp_get,prp_delete,prp_copy,prp_close); + + /* Check arguments. */ + if(NULL == (pclass = H5I_object_verify(cls_id, H5I_GENPROP_CLS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); + if(size > 0 && def_value == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); + + /* Create the new property list class */ + if((ret_value = H5P_register(pclass, name, size, def_value, prp_create, prp_set, prp_get, prp_delete, prp_copy, NULL, prp_close)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class"); + +done: + FUNC_LEAVE_API(ret_value); +} /* H5Pregister1() */ + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + diff --git a/src/H5Pint.c b/src/H5Pint.c new file mode 100644 index 0000000..3147020 --- /dev/null +++ b/src/H5Pint.c @@ -0,0 +1,4448 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: Quincey Koziol + * + * Purpose: Generic Property Functions + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5P_PACKAGE /*suppress error about including H5Ppkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5P_init_interface + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Ppkg.h" /* Property lists */ + +/****************/ +/* Local Macros */ +/****************/ + +#define H5P_DEFAULT_SKIPLIST_HEIGHT 8 + + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Typedef for checking for duplicate class names in parent class */ +typedef struct { + const H5P_genclass_t *parent; /* Pointer to parent class */ + const char *name; /* Pointer to name to check */ +} H5P_check_class_t; + + +/********************/ +/* Local Prototypes */ +/********************/ + +/* General helper routines */ +static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type); +static herr_t H5P_free_prop(H5P_genprop_t *prop); +static int H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2); + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* + * Predefined property list classes. These are initialized at runtime by + * H5P_init_interface() in this source file. + */ +hid_t H5P_CLS_ROOT_g = FAIL; +hid_t H5P_CLS_OBJECT_CREATE_g = FAIL; +hid_t H5P_CLS_FILE_CREATE_g = FAIL; +hid_t H5P_CLS_FILE_ACCESS_g = FAIL; +hid_t H5P_CLS_DATASET_CREATE_g = FAIL; +hid_t H5P_CLS_DATASET_ACCESS_g = FAIL; +hid_t H5P_CLS_DATASET_XFER_g = FAIL; +hid_t H5P_CLS_FILE_MOUNT_g = FAIL; +hid_t H5P_CLS_GROUP_CREATE_g = FAIL; +hid_t H5P_CLS_GROUP_ACCESS_g = FAIL; +hid_t H5P_CLS_DATATYPE_CREATE_g = FAIL; +hid_t H5P_CLS_DATATYPE_ACCESS_g = FAIL; +hid_t H5P_CLS_ATTRIBUTE_CREATE_g = FAIL; +hid_t H5P_CLS_OBJECT_COPY_g = FAIL; +hid_t H5P_CLS_LINK_CREATE_g = FAIL; +hid_t H5P_CLS_LINK_ACCESS_g = FAIL; +hid_t H5P_CLS_STRING_CREATE_g = FAIL; + +/* + * Predefined property lists for each predefined class. These are initialized + * at runtime by H5P_init_interface() in this source file. + */ +hid_t H5P_LST_FILE_CREATE_g = FAIL; +hid_t H5P_LST_FILE_ACCESS_g = FAIL; +hid_t H5P_LST_DATASET_CREATE_g = FAIL; +hid_t H5P_LST_DATASET_ACCESS_g = FAIL; +hid_t H5P_LST_DATASET_XFER_g = FAIL; +hid_t H5P_LST_FILE_MOUNT_g = FAIL; +hid_t H5P_LST_GROUP_CREATE_g = FAIL; +hid_t H5P_LST_GROUP_ACCESS_g = FAIL; +hid_t H5P_LST_DATATYPE_CREATE_g = FAIL; +hid_t H5P_LST_DATATYPE_ACCESS_g = FAIL; +hid_t H5P_LST_ATTRIBUTE_CREATE_g = FAIL; +hid_t H5P_LST_OBJECT_COPY_g = FAIL; +hid_t H5P_LST_LINK_CREATE_g = FAIL; +hid_t H5P_LST_LINK_ACCESS_g = FAIL; + +/* Root property list class library initialization object */ +const H5P_libclass_t H5P_CLS_ROOT[1] = {{ + "root", /* Class name for debugging */ + NULL, /* Parent class ID */ + &H5P_CLS_ROOT_g, /* Pointer to class ID */ + NULL, /* Pointer to default property list ID */ + NULL, /* Default property registration routine */ + NULL, /* Class creation callback */ + NULL, /* Class creation callback info */ + NULL, /* Class copy callback */ + NULL, /* Class copy callback info */ + NULL, /* Class close callback */ + NULL /* Class close callback info */ +}}; + +/* Group access property list class library initialization object */ +/* (move to proper source code file when used for real) */ +const H5P_libclass_t H5P_CLS_GACC[1] = {{ + "group access", /* Class name for debugging */ + &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */ + &H5P_CLS_GROUP_ACCESS_g, /* Pointer to class ID */ + &H5P_LST_GROUP_ACCESS_g, /* Pointer to default property list ID */ + NULL, /* Default property registration routine */ + NULL, /* Class creation callback */ + NULL, /* Class creation callback info */ + NULL, /* Class copy callback */ + NULL, /* Class copy callback info */ + NULL, /* Class close callback */ + NULL /* Class close callback info */ +}}; + +/* Dataset access property list class library initialization object */ +/* (move to proper source code file when used for real) */ +const H5P_libclass_t H5P_CLS_DACC[1] = {{ + "dataset access", /* Class name for debugging */ + &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */ + &H5P_CLS_DATASET_ACCESS_g, /* Pointer to class ID */ + &H5P_LST_DATASET_ACCESS_g, /* Pointer to default property list ID */ + NULL, /* Default property registration routine */ + NULL, /* Class creation callback */ + NULL, /* Class creation callback info */ + NULL, /* Class copy callback */ + NULL, /* Class copy callback info */ + NULL, /* Class close callback */ + NULL /* Class close callback info */ +}}; + +/* Datatype creation property list class library initialization object */ +/* (move to proper source code file when used for real) */ +const H5P_libclass_t H5P_CLS_TCRT[1] = {{ + "datatype create", /* Class name for debugging */ + &H5P_CLS_OBJECT_CREATE_g, /* Parent class ID */ + &H5P_CLS_DATATYPE_CREATE_g, /* Pointer to class ID */ + &H5P_LST_DATATYPE_CREATE_g, /* Pointer to default property list ID */ + NULL, /* Default property registration routine */ + NULL, /* Class creation callback */ + NULL, /* Class creation callback info */ + NULL, /* Class copy callback */ + NULL, /* Class copy callback info */ + NULL, /* Class close callback */ + NULL /* Class close callback info */ +}}; + +/* Datatype access property list class library initialization object */ +/* (move to proper source code file when used for real) */ +const H5P_libclass_t H5P_CLS_TACC[1] = {{ + "datatype access", /* Class name for debugging */ + &H5P_CLS_LINK_ACCESS_g, /* Parent class ID */ + &H5P_CLS_DATATYPE_ACCESS_g, /* Pointer to class ID */ + &H5P_LST_DATATYPE_ACCESS_g, /* Pointer to default property list ID */ + NULL, /* Default property registration routine */ + NULL, /* Class creation callback */ + NULL, /* Class creation callback info */ + NULL, /* Class copy callback */ + NULL, /* Class copy callback info */ + NULL, /* Class close callback */ + NULL /* Class close callback info */ +}}; + + +/* Library property list classes defined in other code modules */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_OCRT[1]; /* Object creation */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_STRCRT[1]; /* String create */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_LACC[1]; /* Link access */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_GCRT[1]; /* Group create */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_OCPY[1]; /* Object copy */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_FCRT[1]; /* File creation */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_FACC[1]; /* File access */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_DCRT[1]; /* Dataset creation */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_DXFR[1]; /* Data transfer */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_FMNT[1]; /* File mount */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_ACRT[1]; /* Attribute creation */ +H5_DLLVAR const H5P_libclass_t H5P_CLS_LCRT[1]; /* Link creation */ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Track the revision count of a class, to make comparisons faster */ +static unsigned H5P_next_rev = 0; +#define H5P_GET_NEXT_REV (H5P_next_rev++) + +/* List of all property list classes in the library */ +/* (order here is not important, they will be initialized in the proper + * order according to their parent class dependencies) + */ +static H5P_libclass_t const * const init_class[] = { + H5P_CLS_ROOT, /* Root */ + H5P_CLS_OCRT, /* Object create */ + H5P_CLS_STRCRT, /* String create */ + H5P_CLS_LACC, /* Link access */ + H5P_CLS_GCRT, /* Group create */ + H5P_CLS_OCPY, /* Object copy */ + H5P_CLS_GACC, /* Group access */ + H5P_CLS_FCRT, /* File creation */ + H5P_CLS_FACC, /* File access */ + H5P_CLS_DCRT, /* Dataset creation */ + H5P_CLS_DACC, /* Dataset access */ + H5P_CLS_DXFR, /* Data transfer */ + H5P_CLS_FMNT, /* File mount */ + H5P_CLS_TCRT, /* Datatype creation */ + H5P_CLS_TACC, /* Datatype access */ + H5P_CLS_ACRT, /* Attribute creation */ + H5P_CLS_LCRT /* Link creation */ +}; + +/* Declare a free list to manage the H5P_genclass_t struct */ +H5FL_DEFINE_STATIC(H5P_genclass_t); + +/* Declare a free list to manage the H5P_genprop_t struct */ +H5FL_DEFINE_STATIC(H5P_genprop_t); + +/* Declare a free list to manage the H5P_genplist_t struct */ +H5FL_DEFINE_STATIC(H5P_genplist_t); + + +/*-------------------------------------------------------------------------- + NAME + H5P_do_prop_cb1 + PURPOSE + Internal routine to call a property list callback routine and update + the property list accordingly. + USAGE + herr_t H5P_do_prop_cb1(slist,prop,cb) + H5SL_t *slist; IN/OUT: Skip list to hold changed properties + H5P_genprop_t *prop; IN: Property to call callback for + H5P_prp_cb1_t *cb; IN: Callback routine to call + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Calls the callback routine passed in. If the callback routine changes + the property value, then the property is duplicated and added to skip list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb) +{ + void *tmp_value=NULL; /* Temporary value buffer */ + H5P_genprop_t *pcopy=NULL; /* Copy of property to insert into skip list */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_do_prop_cb1); + + /* Allocate space for a temporary copy of the property value */ + if(NULL == (tmp_value = H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); + HDmemcpy(tmp_value,prop->value,prop->size); + + /* Call "type 1" callback ('create', 'copy' or 'close') */ + if(cb(prop->name,prop->size,tmp_value) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed"); + + /* Check if the property value changed */ + if(HDmemcmp(tmp_value,prop->value,prop->size)) { + /* Make a copy of the class's property */ + if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + + /* Copy the changed value into the new property */ + HDmemcpy(pcopy->value,tmp_value,prop->size); + + /* Insert the changed property into the property list */ + if(H5P_add_prop(slist,pcopy) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into skip list"); + } /* end if */ + +done: + /* Release the temporary value buffer */ + if(tmp_value!=NULL) + H5MM_xfree(tmp_value); + + /* Cleanup on failure */ + if(ret_value<0) { + if(pcopy!=NULL) + H5P_free_prop(pcopy); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5P_do_prop_cb1() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_init + * + * Purpose: Initialize the interface from some other layer. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, March 4, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_init, FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_init() */ + + +/*-------------------------------------------------------------------------- +NAME + H5P_init_interface -- Initialize interface-specific information +USAGE + herr_t H5P_init_interface() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------*/ +static herr_t +H5P_init_interface(void) +{ + size_t tot_init; /* Total # of classes initialized */ + size_t pass_init; /* # of classes initialized in each pass */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_init_interface) + + /* + * Initialize the Generic Property class & object groups. + */ + if(H5I_register_type(H5I_GENPROP_CLS, (size_t)H5I_GENPROPCLS_HASHSIZE, 0, (H5I_free_t)H5P_close_class) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group") + if(H5I_register_type(H5I_GENPROP_LST, (size_t)H5I_GENPROPOBJ_HASHSIZE, 0, (H5I_free_t)H5P_close) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group") + + /* Repeatedly pass over the list of property list classes for the library, + * initializing each class if it's parent class is initialized, until no + * more progress is made. + */ + tot_init = 0; + do { + size_t u; /* Local index variable */ + + /* Reset pass initialization counter */ + pass_init = 0; + + /* Make a pass over all the library's property list classes */ + for(u = 0; u < NELMTS(init_class); u++) { + H5P_libclass_t const *lib_class = init_class[u]; /* Current class to operate on */ + + /* Check if the current class hasn't been initialized and can be now */ + HDassert(lib_class->class_id); + if(*lib_class->class_id == (-1) && (lib_class->par_class_id == NULL + || *lib_class->par_class_id > 0)) { + H5P_genclass_t *par_pclass = NULL; /* Parent class of new class */ + H5P_genclass_t *new_pclass; /* New property list class created */ + + /* Sanity check - only the root class is not allowed to have a parent class */ + HDassert(lib_class->par_class_id || lib_class == H5P_CLS_ROOT); + + /* Check for parent class */ + if(lib_class->par_class_id) { + /* Get the pointer to the parent class */ + if(NULL == (par_pclass = H5I_object(*lib_class->par_class_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") + } /* end if */ + + /* Allocate the new class */ + if(NULL == (new_pclass = H5P_create_class(par_pclass, lib_class->name, 1, lib_class->create_func, lib_class->create_data, lib_class->copy_func, lib_class->copy_data, lib_class->close_func, lib_class->close_data))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed") + + /* Call routine to register properties for class */ + if(lib_class->reg_prop_func && (*lib_class->reg_prop_func)(new_pclass) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register properties") + + /* Register the new class */ + if((*lib_class->class_id = H5I_register(H5I_GENPROP_CLS, new_pclass)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class") + + /* Only register the default property list if it hasn't been created yet */ + if(lib_class->def_plist_id && *lib_class->def_plist_id == (-1)) { + /* Register the default property list for the new class*/ + if((*lib_class->def_plist_id = H5P_create_id(new_pclass)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list for class") + } /* end if */ + + /* Increment class initialization counters */ + pass_init++; + tot_init++; + } /* end if */ + } /* end for */ + } while(pass_init > 0); + + /* Verify that all classes were initialized */ + HDassert(tot_init == NELMTS(init_class)); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_init_interface() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_term_interface + PURPOSE + Terminate various H5P objects + USAGE + void H5P_term_interface() + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Release the atom group and any other resources allocated. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Can't report errors... + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5P_term_interface(void) +{ + int nlist=0; + int nclass=0; + int n=0; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_term_interface); + + if(H5_interface_initialize_g) { + /* Destroy HDF5 library property classes & lists */ + + /* Check if there are any open property list classes or lists */ + nclass = H5I_nmembers(H5I_GENPROP_CLS); + nlist = H5I_nmembers(H5I_GENPROP_LST); + n=nclass+nlist; + + /* If there are any open classes or groups, attempt to get rid of them. */ + if(n) { + /* Clear the lists */ + if(nlist>0) { + H5I_clear_type(H5I_GENPROP_LST, FALSE); + + /* Reset the default property lists, if they've been closed */ + if(H5I_nmembers(H5I_GENPROP_LST)==0) { + H5P_LST_FILE_CREATE_g = + H5P_LST_FILE_ACCESS_g = + H5P_LST_DATASET_CREATE_g = + H5P_LST_DATASET_ACCESS_g = + H5P_LST_DATASET_XFER_g = + H5P_LST_GROUP_CREATE_g = + H5P_LST_GROUP_ACCESS_g = + H5P_LST_DATATYPE_CREATE_g = + H5P_LST_DATATYPE_ACCESS_g = + H5P_LST_ATTRIBUTE_CREATE_g = + H5P_LST_OBJECT_COPY_g = + H5P_LST_LINK_CREATE_g = + H5P_LST_LINK_ACCESS_g = + H5P_LST_FILE_MOUNT_g = (-1); + } /* end if */ + } /* end if */ + + /* Only attempt to close the classes after all the lists are closed */ + if(nlist==0 && nclass>0) { + H5I_clear_type(H5I_GENPROP_CLS, FALSE); + + /* Reset the default property lists, if they've been closed */ + if(H5I_nmembers(H5I_GENPROP_CLS)==0) { + H5P_CLS_ROOT_g = + H5P_CLS_OBJECT_CREATE_g = + H5P_CLS_FILE_CREATE_g = + H5P_CLS_FILE_ACCESS_g = + H5P_CLS_DATASET_CREATE_g = + H5P_CLS_DATASET_ACCESS_g = + H5P_CLS_DATASET_XFER_g = + H5P_CLS_GROUP_CREATE_g = + H5P_CLS_GROUP_ACCESS_g = + H5P_CLS_DATATYPE_CREATE_g = + H5P_CLS_DATATYPE_ACCESS_g = + H5P_CLS_STRING_CREATE_g = + H5P_CLS_ATTRIBUTE_CREATE_g = + H5P_CLS_OBJECT_COPY_g = + H5P_CLS_LINK_CREATE_g = + H5P_CLS_LINK_ACCESS_g = + H5P_CLS_FILE_MOUNT_g = (-1); + } /* end if */ + } /* end if */ + } else { + H5I_dec_type_ref(H5I_GENPROP_LST); + n++; /*H5I*/ + H5I_dec_type_ref(H5I_GENPROP_CLS); + n++; /*H5I*/ + + H5_interface_initialize_g = 0; + } + } + FUNC_LEAVE_NOAPI(n); +} + + +/*-------------------------------------------------------------------------- + NAME + H5P_copy_pclass + PURPOSE + Internal routine to copy a generic property class + USAGE + hid_t H5P_copy_pclass(pclass) + H5P_genclass_t *pclass; IN: Property class to copy + RETURNS + Success: valid property class ID on success (non-negative) + Failure: negative + DESCRIPTION + Copy a property class and return the ID. This routine does not make + any callbacks. (They are only make when operating on property lists). + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5P_genclass_t * +H5P_copy_pclass(H5P_genclass_t *pclass) +{ + H5P_genclass_t *new_pclass = NULL; /* Property list class copied */ + H5P_genprop_t *pcopy; /* Copy of property to insert into class */ + H5P_genclass_t *ret_value=NULL; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_copy_pclass); + + assert(pclass); + + /* + * Create new property class object + */ + + /* Create the new property list class */ + if(NULL==(new_pclass=H5P_create_class(pclass->parent, pclass->name, 0, pclass->create_func, pclass->create_data, pclass->copy_func, pclass->copy_data, pclass->close_func, pclass->close_data))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class"); + + /* Copy the properties registered for this class */ + if(pclass->nprops>0) { + H5SL_node_t *curr_node; /* Current node in skip list */ + + /* Walk through the properties in the old class */ + curr_node=H5SL_first(pclass->props); + while(curr_node!=NULL) { + /* Make a copy of the class's property */ + if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property"); + + /* Insert the initialized property into the property list */ + if(H5P_add_prop(new_pclass->props,pcopy) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class"); + + /* Increment property count for class */ + new_pclass->nprops++; + + /* Get the next property node in the list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Set the return value */ + ret_value=new_pclass; + +done: + if(ret_value==NULL && new_pclass) + H5P_close_class(new_pclass); + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_copy_pclass() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_copy_plist + PURPOSE + Internal routine to copy a generic property list + USAGE + hid_t H5P_copy_plist(old_plist_id) + hid_t old_plist_id; IN: Property list ID to copy + RETURNS + Success: valid property list ID on success (non-negative) + Failure: negative + DESCRIPTION + Copy a property list and return the ID. This routine calls the + class 'copy' callback after any property 'copy' callbacks are called + (assuming all property 'copy' callbacks return successfully). + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hid_t +H5P_copy_plist(H5P_genplist_t *old_plist) +{ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genplist_t *new_plist=NULL; /* New property list generated from copy */ + H5P_genprop_t *tmp; /* Temporary pointer to properties */ + H5P_genprop_t *new_prop; /* New property created for copy */ + hid_t new_plist_id; /* Property list ID of new list created */ + H5SL_node_t *curr_node; /* Current node in skip list */ + H5SL_t *seen=NULL; /* Skip list containing properties already seen */ + size_t nseen; /* Number of items 'seen' */ + hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */ + hid_t ret_value=FAIL; /* return value */ + + FUNC_ENTER_NOAPI(H5P_copy_plist, FAIL); + + assert(old_plist); + + /* + * Create new property list object + */ + + /* Allocate room for the property list */ + if(NULL==(new_plist = H5FL_CALLOC(H5P_genplist_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,"memory allocation failed"); + + /* Set class state */ + new_plist->pclass = old_plist->pclass; + new_plist->nprops = 0; /* Initially the plist has the same number of properties as the class */ + new_plist->class_init = 0; /* Initially, wait until the class callback finishes to set */ + + /* Initialize the skip list to hold the changed properties */ + if((new_plist->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties"); + + /* Create the skip list for deleted properties */ + if((new_plist->del = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties"); + + /* Create the skip list to hold names of properties already seen + * (This prevents a property in the class hierarchy from having it's + * 'create' callback called, if a property in the class hierarchy has + * already been seen) + */ + if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT))== NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); + nseen = 0; + + /* Cycle through the deleted properties & copy them into the new list's deleted section */ + if(H5SL_count(old_plist->del)>0) { + curr_node=H5SL_first(old_plist->del); + while(curr_node) { + char *new_name; /* Pointer to new name */ + + /* Duplicate string for insertion into new deleted property skip list */ + if((new_name=H5MM_xstrdup((char *)H5SL_item(curr_node))) == NULL) + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); + + /* Insert property name into deleted list */ + if(H5SL_insert(new_plist->del,new_name,new_name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); + + /* Add property name to "seen" list */ + if(H5SL_insert(seen,new_name,new_name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + nseen++; + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Cycle through the properties and copy them also */ + if(H5SL_count(old_plist->props)>0) { + curr_node=H5SL_first(old_plist->props); + while(curr_node) { + /* Get a pointer to the node's property */ + tmp=H5SL_item(curr_node); + + /* Make a copy of the list's property */ + if((new_prop=H5P_dup_prop(tmp,H5P_PROP_WITHIN_LIST)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + + /* Call property copy callback, if it exists */ + if(new_prop->copy) { + if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value) < 0) { + H5P_free_prop(new_prop); + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + } /* end if */ + } /* end if */ + + /* Insert the initialized property into the property list */ + if(H5P_add_prop(new_plist->props,new_prop) < 0) { + H5P_free_prop(new_prop); + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list"); + } /* end if */ + + /* Add property name to "seen" list */ + if(H5SL_insert(seen,new_prop->name,new_prop->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + nseen++; + + /* Increment the number of properties in list */ + new_plist->nprops++; + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* + * Check for copying class properties (up through list of parent classes also), + * initialize each with default value & make property 'copy' callback. + */ + tclass=old_plist->pclass; + has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0); + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Walk through the properties in the old class */ + curr_node=H5SL_first(tclass->props); + while(curr_node!=NULL) { + /* Get pointer to property from node */ + tmp=H5SL_item(curr_node); + + /* Only "copy" properties we haven't seen before */ + if(nseen==0 || H5SL_search(seen,tmp->name) == NULL) { + /* Call property creation callback, if it exists */ + if(tmp->copy) { + /* Call the callback & insert changed value into skip list (if necessary) */ + if(H5P_do_prop_cb1(new_plist->props,tmp,tmp->copy) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't create property"); + } /* end if */ + + /* Add property name to "seen" list, if we have other classes to work on */ + if(has_parent_class) { + if(H5SL_insert(seen,tmp->name,tmp->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + nseen++; + } /* end if */ + + /* Increment the number of properties in list */ + new_plist->nprops++; + } /* end if */ + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* Increment the number of property lists derived from class */ + if(H5P_access_class(new_plist->pclass,H5P_MOD_INC_LST) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment class ref count"); + + /* Get an atom for the property list */ + if((new_plist_id = H5I_register(H5I_GENPROP_LST, new_plist)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list"); + + /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */ + new_plist->plist_id=new_plist_id; + + /* Call the class callback (if it exists) now that we have the property list ID */ + if(new_plist->pclass->copy_func!=NULL) { + if((new_plist->pclass->copy_func)(new_plist_id,old_plist->plist_id,old_plist->pclass->copy_data) < 0) { + /* Delete ID, ignore return value */ + H5I_remove(new_plist_id); + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); + } /* end if */ + } /* end if */ + + /* Set the class initialization flag */ + new_plist->class_init=1; + + /* Set the return value */ + ret_value=new_plist_id; + +done: + /* Release the list of 'seen' properties */ + if(seen!=NULL) + H5SL_close(seen); + + if(ret_value<0 && new_plist) + H5P_close(new_plist); + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_copy_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_dup_prop + PURPOSE + Internal routine to duplicate a property + USAGE + H5P_genprop_t *H5P_dup_prop(oprop) + H5P_genprop_t *oprop; IN: Pointer to property to copy + H5P_prop_within_t type; IN: Type of object the property will be inserted into + RETURNS + Returns a pointer to the newly created duplicate of a property on success, + NULL on failure. + DESCRIPTION + Allocates memory and copies property information into a new property object. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5P_genprop_t * +H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type) +{ + H5P_genprop_t *prop=NULL; /* Pointer to new property copied */ + H5P_genprop_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_dup_prop); + + assert(oprop); + assert(type!=H5P_PROP_WITHIN_UNKNOWN); + + /* Allocate the new property */ + if(NULL==(prop = H5FL_MALLOC (H5P_genprop_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Copy basic property information */ + HDmemcpy(prop,oprop,sizeof(H5P_genprop_t)); + + /* Check if we should duplicate the name or share it */ + + /* Duplicating property for a class */ + if(type==H5P_PROP_WITHIN_CLASS) { + assert(oprop->type==H5P_PROP_WITHIN_CLASS); + assert(oprop->shared_name==0); + + /* Duplicate name */ + prop->name = H5MM_xstrdup(oprop->name); + } /* end if */ + /* Duplicating property for a list */ + else { + /* Check if we are duplicating a property from a list or a class */ + + /* Duplicating a property from a list */ + if(oprop->type==H5P_PROP_WITHIN_LIST) { + /* If the old property's name wasn't shared, we have to copy it here also */ + if(!oprop->shared_name) + prop->name = H5MM_xstrdup(oprop->name); + } /* end if */ + /* Duplicating a property from a class */ + else { + assert(oprop->type==H5P_PROP_WITHIN_CLASS); + assert(oprop->shared_name==0); + + /* Share the name */ + prop->shared_name=1; + + /* Set the type */ + prop->type=type; + } /* end else */ + } /* end else */ + + /* Duplicate current value, if it exists */ + if(oprop->value!=NULL) { + assert(prop->size>0); + if(NULL==(prop->value = H5MM_malloc (prop->size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy(prop->value,oprop->value,prop->size); + } /* end if */ + + /* Set return value */ + ret_value=prop; + +done: + /* Free any resources allocated */ + if(ret_value==NULL) { + if(prop!=NULL) { + if(prop->name!=NULL) + H5MM_xfree(prop->name); + if(prop->value!=NULL) + H5MM_xfree(prop->value); + H5FL_FREE(H5P_genprop_t,prop); + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_dup_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_create_prop + PURPOSE + Internal routine to create a new property + USAGE + H5P_genprop_t *H5P_create_prop(name,size,type,value,prp_create,prp_set, + prp_get,prp_delete,prp_close) + const char *name; IN: Name of property to register + size_t size; IN: Size of property in bytes + H5P_prop_within_t type; IN: Type of object the property will be inserted into + void *value; IN: Pointer to buffer containing value for property + H5P_prp_create_func_t prp_create; IN: Function pointer to property + creation callback + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback + H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback + H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns a pointer to the newly created property on success, + NULL on failure. + DESCRIPTION + Allocates memory and copies property information into a new property object. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5P_genprop_t * +H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type, + const void *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) +{ + H5P_genprop_t *prop=NULL; /* Pointer to new property copied */ + H5P_genprop_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_create_prop); + + assert(name); + assert((size>0 && value!=NULL) || (size==0)); + assert(type!=H5P_PROP_WITHIN_UNKNOWN); + + /* Allocate the new property */ + if(NULL==(prop = H5FL_MALLOC (H5P_genprop_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Set the property initial values */ + prop->name = H5MM_xstrdup(name); /* Duplicate name */ + prop->shared_name=0; + prop->size=size; + prop->type=type; + + /* Duplicate value, if it exists */ + if(value!=NULL) { + if(NULL==(prop->value = H5MM_malloc (prop->size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy(prop->value,value,prop->size); + } /* end if */ + else + prop->value=NULL; + + /* Set the function pointers */ + prop->create=prp_create; + prop->set=prp_set; + prop->get=prp_get; + prop->del=prp_delete; + prop->copy=prp_copy; + /* Use custom comparison routine if available, otherwise default to memcmp() */ + if(prp_cmp!=NULL) + prop->cmp=prp_cmp; + else + prop->cmp=&memcmp; + prop->close=prp_close; + + /* Set return value */ + ret_value=prop; + +done: + /* Free any resources allocated */ + if(ret_value==NULL) { + if(prop!=NULL) { + if(prop->name!=NULL) + H5MM_xfree(prop->name); + if(prop->value!=NULL) + H5MM_xfree(prop->value); + H5FL_FREE(H5P_genprop_t,prop); + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_create_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_add_prop + PURPOSE + Internal routine to insert a property into a property skip list + USAGE + herr_t H5P_add_prop(slist, prop) + H5SL_t *slist; IN/OUT: Pointer to skip list of properties + H5P_genprop_t *prop; IN: Pointer to property to insert + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Inserts a property into a skip list of properties. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_add_prop(H5SL_t *slist, H5P_genprop_t *prop) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_add_prop,FAIL); + + assert(slist); + assert(prop); + assert(prop->type!=H5P_PROP_WITHIN_UNKNOWN); + + /* Insert property into skip list */ + if(H5SL_insert(slist,prop,prop->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into skip list"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_add_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_find_prop_plist + PURPOSE + Internal routine to check for a property in a property list's skip list + USAGE + H5P_genprop_t *H5P_find_prop(plist, name) + H5P_genplist_t *plist; IN: Pointer to property list to check + const char *name; IN: Name of property to check for + RETURNS + Returns pointer to property on success, NULL on failure. + DESCRIPTION + Checks for a property in a property list's skip list of properties. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5P_genprop_t * +H5P_find_prop_plist(H5P_genplist_t *plist, const char *name) +{ + H5P_genprop_t *ret_value; /* Property pointer return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_plist); + + assert(plist); + assert(name); + + /* Check if the property has been deleted from list */ + if(H5SL_search(plist->del,name)!=NULL) { + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list"); + } /* end if */ + else { + /* Get the property data from the skip list */ + if((ret_value=H5SL_search(plist->props,name)) == NULL) { + H5P_genclass_t *tclass; /* Temporary class pointer */ + + /* Couldn't find property in list itself, start searching through class info */ + tclass=plist->pclass; + while(tclass!=NULL) { + /* Find the property in the class */ + if((ret_value=H5SL_search(tclass->props,name))!=NULL) + /* Got pointer to property - leave now */ + break; + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* Check if we haven't found the property */ + if(ret_value==NULL) + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list"); + } /* end else */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_find_prop_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_find_prop_pclass + PURPOSE + Internal routine to check for a property in a class skip list + USAGE + H5P_genprop_t *H5P_find_prop_class(pclass, name) + H5P_genclass *pclass; IN: Pointer generic property class to check + const char *name; IN: Name of property to check for + RETURNS + Returns pointer to property on success, NULL on failure. + DESCRIPTION + Checks for a property in a class's skip list of properties. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5P_genprop_t * +H5P_find_prop_pclass(H5P_genclass_t *pclass, const char *name) +{ + H5P_genprop_t *ret_value; /* Property pointer return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_find_prop_pclass); + + assert(pclass); + assert(name); + + /* Get the property from the skip list */ + if((ret_value=H5SL_search(pclass->props,name)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,NULL,"can't find property in skip list"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_find_prop_pclass() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_free_prop + PURPOSE + Internal routine to destroy a property node + USAGE + herr_t H5P_free_prop(prop) + H5P_genprop_t *prop; IN: Pointer to property to destroy + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Releases all the memory for a property list. Does _not_ call the + properties 'close' callback, that should already have been done. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_free_prop(H5P_genprop_t *prop) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop); + + assert(prop); + + /* Release the property value if it exists */ + if(prop->value) + H5MM_xfree(prop->value); + + /* Only free the name if we own it */ + if(prop->shared_name==0) + H5MM_xfree(prop->name); + + H5FL_FREE(H5P_genprop_t,prop); + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5P_free_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_free_prop_cb + PURPOSE + Internal routine to properties from a property skip list + USAGE + herr_t H5P_free_prop_cb(item, key, op_data) + void *item; IN/OUT: Pointer to property + void *key; IN/OUT: Pointer to property key + void *_make_cb; IN: Whether to make property callbacks or not + RETURNS + Returns zero on success, negative on failure. + DESCRIPTION + Calls the property 'close' callback for a property & frees property + info. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_free_prop_cb(void *item, void UNUSED *key, void *op_data) +{ + H5P_genprop_t *tprop=(H5P_genprop_t *)item; /* Temporary pointer to property */ + unsigned make_cb=*(unsigned *)op_data; /* Whether to make property 'close' callback */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_prop_cb); + + assert(tprop); + + /* Call the close callback and ignore the return value, there's nothing we can do about it */ + if(make_cb && tprop->close!=NULL) + (tprop->close)(tprop->name,tprop->size,tprop->value); + + /* Free the property, ignoring return value, nothing we can do */ + H5P_free_prop(tprop); + + FUNC_LEAVE_NOAPI(0); +} /* H5P_free_prop_cb() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_free_del_name_cb + PURPOSE + Internal routine to free 'deleted' property name + USAGE + herr_t H5P_free_del_name_cb(item, key, op_data) + void *item; IN/OUT: Pointer to deleted name + void *key; IN/OUT: Pointer to key + void *op_data; IN: Operator callback data (unused) + RETURNS + Returns zero on success, negative on failure. + DESCRIPTION + Frees the deleted property name + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_free_del_name_cb(void *item, void UNUSED *key, void UNUSED *op_data) +{ + char *del_name=(char *)item; /* Temporary pointer to deleted name */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_free_del_name_cb); + + assert(del_name); + + /* Free the name */ + H5MM_xfree(del_name); + + FUNC_LEAVE_NOAPI(0); +} /* H5P_free_del_name_cb() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_access_class + PURPOSE + Internal routine to increment or decrement list & class dependancies on a + property list class + USAGE + herr_t H5P_access_class(pclass,mod) + H5P_genclass_t *pclass; IN: Pointer to class to modify + H5P_class_mod_t mod; IN: Type of modification to class + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Increment/Decrement the class or list dependancies for a given class. + This routine is the final arbiter on decisions about actually releasing a + class in memory, such action is only taken when the reference counts for + both dependent classes & lists reach zero. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_access_class); + + assert(pclass); + assert(mod>H5P_MOD_ERR && modclasses++; + break; + + case H5P_MOD_DEC_CLS: /* Decrement the dependant class count*/ + pclass->classes--; + break; + + case H5P_MOD_INC_LST: /* Increment the dependant list count*/ + pclass->plists++; + break; + + case H5P_MOD_DEC_LST: /* Decrement the dependant list count*/ + pclass->plists--; + break; + + case H5P_MOD_INC_REF: /* Increment the ID reference count*/ + /* Reset the deleted flag if incrementing the reference count */ + if(pclass->deleted) + pclass->deleted=0; + pclass->ref_count++; + break; + + case H5P_MOD_DEC_REF: /* Decrement the ID reference count*/ + pclass->ref_count--; + + /* Mark the class object as deleted if reference count drops to zero */ + if(pclass->ref_count==0) + pclass->deleted=1; + break; + + case H5P_MOD_ERR: + case H5P_MOD_MAX: + assert(0 && "Invalid H5P class modification"); + } /* end switch */ + + /* Check if we can release the class information now */ + if(pclass->deleted && pclass->plists==0 && pclass->classes==0 ) { + H5P_genclass_t *par_class=pclass->parent; /* Pointer to class's parent */ + + assert(pclass->name); + H5MM_xfree(pclass->name); + + /* Free the class properties without making callbacks */ + if(pclass->props) { + unsigned make_cb=0; + + H5SL_destroy(pclass->props,H5P_free_prop_cb,&make_cb); + } /* end if */ + + H5FL_FREE(H5P_genclass_t,pclass); + + /* Reduce the number of dependent classes on parent class also */ + if(par_class!=NULL) + H5P_access_class(par_class, H5P_MOD_DEC_CLS); + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5P_access_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_check_class + PURPOSE + Internal callback routine to check for duplicated names in parent class. + USAGE + int H5P_check_class(obj, id, key) + H5P_genclass_t *obj; IN: Pointer to class + hid_t id; IN: ID of object being looked at + const void *key; IN: Pointer to information used to compare + classes. + RETURNS + Returns >0 on match, 0 on no match and <0 on failure. + DESCRIPTION + Checks whether a property list class has the same parent and name as a + new class being created. This is a callback routine for H5I_search() + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5P_check_class(void *_obj, hid_t UNUSED id, void *_key) +{ + H5P_genclass_t *obj=(H5P_genclass_t *)_obj; /* Pointer to the class for this ID */ + const H5P_check_class_t *key=(const H5P_check_class_t *)_key; /* Pointer to key information for comparison */ + int ret_value=0; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_check_class); + + assert(obj); + assert(H5I_GENPROP_CLS==H5I_get_type(id)); + assert(key); + + /* Check if the class object has the same parent as the new class */ + if(obj->parent==key->parent) { + /* Check if they have the same name */ + if(HDstrcmp(obj->name,key->name)==0) + ret_value=1; /* Indicate a match */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5P_check_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_create_class + PURPOSE + Internal routine to create a new property list class. + USAGE + H5P_genclass_t H5P_create_class(par_class, name, internal, + cls_create, create_data, cls_close, close_data) + H5P_genclass_t *par_class; IN: Pointer to parent class + const char *name; IN: Name of class we are creating + unsigned internal; IN: Whether this is an internal class or not + H5P_cls_create_func_t; IN: The callback function to call when each + property list in this class is created. + void *create_data; IN: Pointer to user data to pass along to class + creation callback. + H5P_cls_copy_func_t; IN: The callback function to call when each + property list in this class is copied. + void *copy_data; IN: Pointer to user data to pass along to class + copy callback. + H5P_cls_close_func_t; IN: The callback function to call when each + property list in this class is closed. + void *close_data; IN: Pointer to user data to pass along to class + close callback. + RETURNS + Returns a pointer to the newly created property list class on success, + NULL on failure. + DESCRIPTION + Allocates memory and attaches a class to the property list class hierarchy. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5P_genclass_t * +H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned internal, + 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) +{ + H5P_genclass_t *pclass=NULL; /* Property list class created */ + H5P_genclass_t *ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_create_class, NULL) + + assert(name); + /* Allow internal classes to break some rules */ + /* (This allows the root of the tree to be created with this routine -QAK) */ + if(!internal) { + assert(par_class); + } + + /* Allocate room for the class */ + if(NULL==(pclass = H5FL_CALLOC(H5P_genclass_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); + + /* Set class state */ + pclass->parent = par_class; + pclass->name = H5MM_xstrdup(name); + pclass->nprops = 0; /* Classes are created without properties initially */ + pclass->plists = 0; /* No properties lists of this class yet */ + pclass->classes = 0; /* No classes derived from this class yet */ + pclass->ref_count = 1; /* This is the first reference to the new class */ + pclass->internal = internal; + pclass->deleted = 0; /* Not deleted yet... :-) */ + pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */ + + /* Create the skip list for properties */ + if((pclass->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for properties"); + + /* Set callback functions and pass-along data */ + pclass->create_func = cls_create; + pclass->create_data = create_data; + pclass->copy_func = cls_copy; + pclass->copy_data = copy_data; + pclass->close_func = cls_close; + pclass->close_data = close_data; + + /* Increment parent class's derived class value */ + if(par_class!=NULL) { + if(H5P_access_class(par_class,H5P_MOD_INC_CLS) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment parent class ref count"); + } /* end if */ + + /* Set return value */ + ret_value=pclass; + +done: + /* Free any resources allocated */ + if(ret_value==NULL) + if(pclass!=NULL) + H5FL_FREE(H5P_genclass_t,pclass); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P_create_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_create + PURPOSE + Internal routine to create a new property list of a property list class. + USAGE + H5P_genplist_t *H5P_create(class) + H5P_genclass_t *class; IN: Property list class create list from + RETURNS + Returns a pointer to the newly created property list on success, + NULL on failure. + DESCRIPTION + Creates a property list of a given class. If a 'create' callback + exists for the property list class, it is called before the + property list is passed back to the user. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + If this routine is called from a library routine other than + H5P_c, the calling routine is responsible for getting an ID for + the property list and calling the class 'create' callback (if one exists) + and also setting the "class_init" flag. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5P_genplist_t * +H5P_create(H5P_genclass_t *pclass) +{ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genplist_t *plist=NULL; /* New property list created */ + H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */ + H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */ + H5P_genplist_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_create); + + assert(pclass); + + /* + * Create new property list object + */ + + /* Allocate room for the property list */ + if(NULL==(plist = H5FL_CALLOC(H5P_genplist_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); + + /* Set class state */ + plist->pclass = pclass; + plist->nprops = 0; /* Initially the plist has the same number of properties as the class */ + plist->class_init = 0; /* Initially, wait until the class callback finishes to set */ + + /* Create the skip list for changed properties */ + if((plist->props = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties"); + + /* Create the skip list for deleted properties */ + if((plist->del = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties"); + + /* Create the skip list to hold names of properties already seen + * (This prevents a property in the class hierarchy from having it's + * 'create' callback called, if a property in the class hierarchy has + * already been seen) + */ + if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties"); + + /* + * Check if we should copy class properties (up through list of parent classes also), + * initialize each with default value & make property 'create' callback. + */ + tclass=pclass; + while(tclass!=NULL) { + if(tclass->nprops>0) { + H5SL_node_t *curr_node; /* Current node in skip list */ + + /* Walk through the properties in the old class */ + curr_node=H5SL_first(tclass->props); + while(curr_node!=NULL) { + /* Get pointer to property from node */ + tmp=H5SL_item(curr_node); + + /* Only "create" properties we haven't seen before */ + if(H5SL_search(seen,tmp->name) == NULL) { + /* Call property creation callback, if it exists */ + if(tmp->create) { + /* Call the callback & insert changed value into skip list (if necessary) */ + if(H5P_do_prop_cb1(plist->props,tmp,tmp->create) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't create property"); + } /* end if */ + + /* Add property name to "seen" list */ + if(H5SL_insert(seen,tmp->name,tmp->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,NULL,"can't insert property into seen skip list"); + + /* Increment the number of properties in list */ + plist->nprops++; + } /* end if */ + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* Increment the number of property lists derived from class */ + if(H5P_access_class(plist->pclass,H5P_MOD_INC_LST) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment class ref count"); + + /* Set return value */ + ret_value=plist; + +done: + /* Release the skip list of 'seen' properties */ + if(seen!=NULL) + H5SL_close(seen); + + /* Release resources allocated on failure */ + if(ret_value==NULL) { + if(plist!=NULL) { + /* Close & free any changed properties */ + if(plist->props) { + unsigned make_cb=1; + + H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb); + } /* end if */ + + /* Close the deleted property skip list */ + if(plist->del) + H5SL_close(plist->del); + + /* Release the property list itself */ + H5FL_FREE(H5P_genplist_t,plist); + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_create() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_create_id + PURPOSE + Internal routine to create a new property list of a property list class. + USAGE + hid_t H5P_create_id(pclass) + H5P_genclass_t *pclass; IN: Property list class create list from + RETURNS + Returns a valid property list ID on success, FAIL on failure. + DESCRIPTION + Creates a property list of a given class. If a 'create' callback + exists for the property list class, it is called before the + property list is passed back to the user. If 'create' callbacks exist for + any individual properties in the property list, they are called before the + class 'create' callback. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hid_t +H5P_create_id(H5P_genclass_t *pclass) +{ + H5P_genplist_t *plist=NULL; /* Property list created */ + hid_t plist_id=FAIL; /* Property list ID */ + hid_t ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_create_id, FAIL); + + assert(pclass); + + /* Create the new property list */ + if((plist=H5P_create(pclass)) == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list"); + + /* Get an atom for the property list */ + if((plist_id = H5I_register(H5I_GENPROP_LST, plist)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list"); + + /* Save the property list ID in the property list struct, for use in the property class's 'close' callback */ + plist->plist_id=plist_id; + + /* Call the class callback (if it exists) now that we have the property list ID */ + if(plist->pclass->create_func!=NULL) { + if((plist->pclass->create_func)(plist_id,plist->pclass->create_data) < 0) { + /* Delete ID, ignore return value */ + H5I_remove(plist_id); + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); + } /* end if */ + } /* end if */ + + /* Set the class initialization flag */ + plist->class_init=1; + + /* Set the return value */ + ret_value=plist_id; + +done: + if(ret_value<0 && plist) + H5P_close(plist); + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_create_id() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_register + PURPOSE + Internal routine to register a new property in a property list class. + USAGE + herr_t H5P_register(class, name, size, default, prp_create, prp_set, prp_get, prp_close) + H5P_genclass_t *class; IN: Property list class to close + const char *name; IN: Name of property to register + size_t size; IN: Size of property in bytes + void *def_value; IN: Pointer to buffer containing default value + for property in newly created property lists + H5P_prp_create_func_t prp_create; IN: Function pointer to property + creation callback + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback + H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback + H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Registers a new property with a property list class. The property will + exist in all property list objects of that class after this routine is + finished. The name of the property must not already exist. The default + property value must be provided and all new property lists created with this + property will have the property value set to the default provided. Any of + the callback routines may be set to NULL if they are not needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'default' pointer for a + zero-sized property may be set to NULL. The property 'create' & 'close' + callbacks are called for zero-sized properties, but the 'set' and 'get' + callbacks are never called. + + The 'create' callback is called when a new property list with this + property is being created. H5P_prp_create_func_t is defined as: + typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, + size_t size, void *initial_value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being created. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *initial_value; IN/OUT: The initial value for the property being created. + (The 'default' value passed to H5Pregister2) + The 'create' routine may modify the value to be set and those changes will + be stored as the initial value of the property. If the 'create' routine + returns a negative value, the new property value is not copied into the + property and the property list creation routine returns an error value. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'delete' callback is called when a property is deleted from a + property list. H5P_prp_del_func_t is defined as: + typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list the property is deleted from. + const char *name; IN: The name of the property being deleted. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value of the property being deleted. + The 'delete' routine may modify the value passed in, but the value is not + used by the library when the 'delete' routine returns. If the + 'delete' routine returns a negative value, the property list deletion + routine returns an error value but the property is still deleted. + + The 'copy' callback is called when a property list with this + property is copied. H5P_prp_copy_func_t is defined as: + typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being copied. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being copied. + The 'copy' routine may modify the value to be copied and those changes will be + stored as the value of the property. If the 'copy' routine returns a + negative value, the new property value is not copied into the property and + the property list copy routine returns an error value. + + The 'compare' callback is called when a property list with this + property is compared to another property list. H5P_prp_compare_func_t is + defined as: + typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, + size_t size); + where the parameters to the callback function are: + const void *value1; IN: The value of the first property being compared. + const void *value2; IN: The value of the second property being compared. + size_t size; IN: The size of the property value + The 'compare' routine may not modify the values to be compared. The + 'compare' routine should return a positive value if VALUE1 is greater than + VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 + and VALUE2 are equal. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_register(H5P_genclass_t *pclass, const char *name, size_t size, + const 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) +{ + H5P_genclass_t *new_class; /* New class pointer */ + H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */ + H5P_genprop_t *pcopy; /* Property copy */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_register, FAIL); + + assert(pclass); + assert(name); + assert((size>0 && def_value!=NULL) || (size==0)); + + /* Check for duplicate named properties */ + if(H5SL_search(pclass->props,name)!=NULL) + HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); + + /* Check if class needs to be split because property lists or classes have + * been created since the last modification was made to the class. + */ + if(pclass->plists>0 || pclass->classes>0) { + if((new_class=H5P_create_class(pclass->parent,pclass->name, + pclass->internal,pclass->create_func,pclass->create_data, + pclass->copy_func,pclass->copy_data, + pclass->close_func,pclass->close_data)) == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy class"); + + /* Walk through the skip list of the old class and copy properties */ + if(pclass->nprops>0) { + H5SL_node_t *curr_node; /* Current node in skip list */ + + /* Walk through the properties in the old class */ + curr_node=H5SL_first(pclass->props); + while(curr_node!=NULL) { + /* Make a copy of the class's property */ + if((pcopy=H5P_dup_prop(H5SL_item(curr_node),H5P_PROP_WITHIN_CLASS)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + + /* Insert the initialized property into the property list */ + if(H5P_add_prop(new_class->props,pcopy) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + + /* Increment property count for class */ + new_class->nprops++; + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Use the new class instead of the old one */ + pclass=new_class; + } /* end if */ + + /* Create property object from parameters */ + if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_CLASS,def_value,prp_create,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); + + /* Insert property into property list class */ + if(H5P_add_prop(pclass->props,new_prop) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + + /* Increment property count for class */ + pclass->nprops++; + + /* Update the revision for the class */ + pclass->revision = H5P_GET_NEXT_REV; + +done: + if(ret_value==FAIL) { + if(new_prop!=NULL) { + if(new_prop->name!=NULL) + H5MM_xfree(new_prop->name); + if(new_prop->value!=NULL) + H5MM_xfree(new_prop->value); + H5FL_FREE(H5P_genprop_t,new_prop); + } /* end if */ + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_register() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_insert + PURPOSE + Internal routine to insert a new property in a property list. + USAGE + herr_t H5P_insert(plist, name, size, value, prp_set, prp_get, prp_close) + H5P_genplist_t *plist; IN: Property list to add property to + const char *name; IN: Name of property to add + size_t size; IN: Size of property in bytes + void *value; IN: Pointer to the value for the property + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_delete_func_t prp_delete; IN: Function pointer to property delete callback + H5P_prp_copy_func_t prp_copy; IN: Function pointer to property copy callback + H5P_prp_compare_func_t prp_cmp; IN: Function pointer to property compare callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Inserts a temporary property into a property list. The property will + exist only in this property list object. The name of the property must not + already exist. The value must be provided unless the property is zero- + sized. Any of the callback routines may be set to NULL if they are not + needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'value' pointer for a + zero-sized property may be set to NULL. The property 'close' callback is + called for zero-sized properties, but the 'set' and 'get' callbacks are + never called. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + size_t size; IN: The size of the property value + void *new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'delete' callback is called when a property is deleted from a + property list. H5P_prp_del_func_t is defined as: + typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name, + size_t size, void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list the property is deleted from. + const char *name; IN: The name of the property being deleted. + size_t size; IN: The size of the property value + void *value; IN/OUT: The value of the property being deleted. + The 'delete' routine may modify the value passed in, but the value is not + used by the library when the 'delete' routine returns. If the + 'delete' routine returns a negative value, the property list deletion + routine returns an error value but the property is still deleted. + + The 'copy' callback is called when a property list with this + property is copied. H5P_prp_copy_func_t is defined as: + typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being copied. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being copied. + The 'copy' routine may modify the value to be copied and those changes will be + stored as the value of the property. If the 'copy' routine returns a + negative value, the new property value is not copied into the property and + the property list copy routine returns an error value. + + The 'compare' callback is called when a property list with this + property is compared to another property list. H5P_prp_compare_func_t is + defined as: + typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2, + size_t size); + where the parameters to the callback function are: + const void *value1; IN: The value of the first property being compared. + const void *value2; IN: The value of the second property being compared. + size_t size; IN: The size of the property value + The 'compare' routine may not modify the values to be compared. The + 'compare' routine should return a positive value if VALUE1 is greater than + VALUE2, a negative value if VALUE2 is greater than VALUE1 and zero if VALUE1 + and VALUE2 are equal. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + size_t size; IN: The size of the property value + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + There is no 'create' callback routine for temporary property list + objects, the initial value is assumed to have any necessary setup already + performed on it. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_insert(H5P_genplist_t *plist, 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) +{ + H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_insert); + + assert(plist); + assert(name); + assert((size>0 && value!=NULL) || (size==0)); + + /* Check for duplicate named properties */ + if(H5SL_search(plist->props,name)!=NULL) + HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); + + /* Check if the property has been deleted */ + if(H5SL_search(plist->del,name)!=NULL) { + /* Remove the property name from the deleted property skip list */ + if(H5SL_remove(plist->del,name) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from deleted skip list"); + + /* Fall through to add property to list */ + } /* end if */ + else { + H5P_genclass_t *tclass; /* Temporary class pointer */ + + /* Check if the property is already in the class hierarchy */ + tclass=plist->pclass; + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Find the property in the class */ + if(H5SL_search(tclass->props,name)!=NULL) + HGOTO_ERROR(H5E_PLIST, H5E_EXISTS, FAIL, "property already exists"); + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* Fall through to add property to list */ + } /* end else */ + + /* Ok to add to property list */ + + /* Create property object from parameters */ + if((new_prop=H5P_create_prop(name,size,H5P_PROP_WITHIN_LIST,value,NULL,prp_set,prp_get,prp_delete,prp_copy,prp_cmp,prp_close)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); + + /* Insert property into property list class */ + if(H5P_add_prop(plist->props,new_prop) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + + /* Increment property count for class */ + plist->nprops++; + +done: + if(ret_value==FAIL) { + if(new_prop!=NULL) { + if(new_prop->name!=NULL) + H5MM_xfree(new_prop->name); + if(new_prop->value!=NULL) + H5MM_xfree(new_prop->value); + H5FL_FREE(H5P_genprop_t,new_prop); + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_insert() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_set + PURPOSE + Internal routine to set a property's value in a property list. + USAGE + herr_t H5P_set(plist, name, value) + H5P_genplist_t *plist; IN: Property list to find property in + const char *name; IN: Name of property to set + void *value; IN: Pointer to the value for the property + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Sets a new value for a property in a property list. The property name + must exist or this routine will fail. If there is a 'set' callback routine + registered for this property, the 'value' will be passed to that routine and + any changes to the 'value' will be used when setting the property value. + The information pointed at by the 'value' pointer (possibly modified by the + 'set' callback) is copied into the property list value and may be changed + by the application making the H5Pset call without affecting the property + value. + + If the 'set' callback routine returns an error, the property value will + not be modified. This routine may not be called for zero-sized properties + and will return an error in that case. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_set(H5P_genplist_t *plist, const char *name, const void *value) +{ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_set, FAIL); + + assert(plist); + assert(name); + assert(value); + + /* Check if the property has been deleted */ + if(H5SL_search(plist->del,name)!=NULL) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + + /* Find property in changed list */ + if((prop=H5SL_search(plist->props,name))!=NULL) { + /* Check for property size >0 */ + if(prop->size==0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size"); + + /* Make a copy of the value and pass to 'set' callback */ + if(prop->set!=NULL) { + void *tmp_value; /* Temporary value for property */ + + /* Make a copy of the current value, in case the callback fails */ + if(NULL==(tmp_value=H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HDmemcpy(tmp_value,value,prop->size); + + /* Call user's callback */ + if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value) < 0) { + H5MM_xfree(tmp_value); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); + } /* end if */ + + /* Copy new [possibly unchanged] value into property value */ + HDmemcpy(prop->value,tmp_value,prop->size); + + /* Free the temporary value buffer */ + H5MM_xfree(tmp_value); + } /* end if */ + /* No 'set' callback, just copy value */ + else + HDmemcpy(prop->value,value,prop->size); + } /* end if */ + else { + /* + * Check if we should set class properties (up through list of parent classes also), + * & make property 'set' callback. + */ + tclass=plist->pclass; + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Find the property in the class */ + if((prop=H5SL_search(tclass->props,name))!=NULL) { + H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */ + + /* Check for property size >0 */ + if(prop->size==0) + HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size"); + + /* Make a copy of the value and pass to 'set' callback */ + if(prop->set!=NULL) { + void *tmp_value; /* Temporary value for property */ + + /* Make a copy of the current value, in case the callback fails */ + if(NULL==(tmp_value=H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HDmemcpy(tmp_value,value,prop->size); + + /* Call user's callback */ + if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value) < 0) { + H5MM_xfree(tmp_value); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); + } /* end if */ + + if(HDmemcmp(tmp_value,prop->value,prop->size)) { + /* Make a copy of the class's property */ + if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); + + /* Copy new value into property value */ + HDmemcpy(pcopy->value,tmp_value,pcopy->size); + + /* Insert the changed property into the property list */ + if(H5P_add_prop(plist->props,pcopy) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); + } /* end if */ + + /* Free the temporary value buffer */ + H5MM_xfree(tmp_value); + } /* end if */ + /* No 'set' callback, just copy value */ + else { + if(HDmemcmp(value,prop->value,prop->size)) { + /* Make a copy of the class's property */ + if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); + + HDmemcpy(pcopy->value,value,pcopy->size); + + /* Insert the changed property into the property list */ + if(H5P_add_prop(plist->props,pcopy) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); + } /* end if */ + } /* end else */ + + /* Leave */ + HGOTO_DONE(SUCCEED); + } /* end while */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* If we get this far, then it wasn't in the list of changed properties, + * nor in the properties in the class hierarchy, indicate an error + */ + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_set() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_exist_plist + PURPOSE + Internal routine to query the existance of a property in a property list. + USAGE + herr_t H5P_exist_plist(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to check for + RETURNS + Success: Positive if the property exists in the property list, zero + if the property does not exist. + Failure: negative value + DESCRIPTION + This routine checks if a property exists within a property list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5P_exist_plist(H5P_genplist_t *plist, const char *name) +{ + htri_t ret_value=FAIL; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_plist); + + assert(plist); + assert(name); + + /* Check for property in deleted property list */ + if(H5SL_search(plist->del,name)!=NULL) + ret_value=0; + else { + /* Check for property in changed property list */ + if(H5SL_search(plist->props,name)!=NULL) + ret_value=1; + else { + H5P_genclass_t *tclass; /* Temporary class pointer */ + + tclass=plist->pclass; + while(tclass!=NULL) { + if(H5SL_search(tclass->props,name)!=NULL) + HGOTO_DONE(1); + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* If we've reached here, we couldn't find the property */ + ret_value=0; + } /* end else */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_exist_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_exist_pclass + PURPOSE + Internal routine to query the existance of a property in a property class. + USAGE + herr_t H5P_exist_pclass(pclass, name) + H5P_genclass_t *pclass; IN: Property class to check + const char *name; IN: Name of property to check for + RETURNS + Success: Positive if the property exists in the property list, zero + if the property does not exist. + Failure: negative value + DESCRIPTION + This routine checks if a property exists within a property list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5P_exist_pclass(H5P_genclass_t *pclass, const char *name) +{ + htri_t ret_value=FAIL; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_exist_pclass); + + assert(pclass); + assert(name); + + /* Check for property in property list */ + if(H5SL_search(pclass->props,name) == NULL) + ret_value=0; + else + ret_value=1; + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_exist_pclass() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_size_plist + PURPOSE + Internal routine to query the size of a property in a property list. + USAGE + herr_t H5P_get_size_plist(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + size_t *size; OUT: Size of property + RETURNS + Success: non-negative value + Failure: negative value + DESCRIPTION + This routine retrieves the size of a property's value in bytes. Zero- + sized properties are allowed and return a value of 0. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_get_size_plist(H5P_genplist_t *plist, const char *name, size_t *size) +{ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_plist); + + assert(plist); + assert(name); + assert(size); + + /* Find property */ + if((prop=H5P_find_prop_plist(plist,name)) == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + + /* Get property size */ + *size=prop->size; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_get_size_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_size_pclass + PURPOSE + Internal routine to query the size of a property in a property class. + USAGE + herr_t H5P_get_size_pclass(pclass, name) + H5P_genclass_t *pclass; IN: Property class to check + const char *name; IN: Name of property to query + size_t *size; OUT: Size of property + RETURNS + Success: non-negative value + Failure: negative value + DESCRIPTION + This routine retrieves the size of a property's value in bytes. Zero- + sized properties are allowed and return a value of 0. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, size_t *size) +{ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_get_size_pclass); + + assert(pclass); + assert(name); + assert(size); + + /* Find property */ + if((prop=H5P_find_prop_pclass(pclass,name)) == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + + /* Get property size */ + *size=prop->size; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_get_size_pclass() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_class + PURPOSE + Internal routine to query the class of a generic property list + USAGE + H5P_genclass_t *H5P_get_class(plist) + H5P_genplist_t *plist; IN: Property list to check + RETURNS + Success: Pointer to the class for a property list + Failure: NULL + DESCRIPTION + This routine retrieves a pointer to the class for a property list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5P_genclass_t * +H5P_get_class(const H5P_genplist_t *plist) +{ + H5P_genclass_t *ret_value; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class); + + HDassert(plist); + + /* Get property size */ + ret_value = plist->pclass; + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_get_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_nprops_plist + PURPOSE + Internal routine to query the number of properties in a property list + USAGE + herr_t H5P_get_nprops_plist(plist, nprops) + H5P_genplist_t *plist; IN: Property list to check + size_t *nprops; OUT: Number of properties in the property list + RETURNS + Success: non-negative value + Failure: negative value + DESCRIPTION + This routine retrieves the number of a properties in a property list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_get_nprops_plist(const H5P_genplist_t *plist, size_t *nprops) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_nprops_plist); + + HDassert(plist); + HDassert(nprops); + + /* Get property size */ + *nprops = plist->nprops; + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5P_get_nprops_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_nprops_pclass + PURPOSE + Internal routine to query the number of properties in a property class + USAGE + herr_t H5P_get_nprops_pclass(pclass, nprops) + H5P_genclass_t *pclass; IN: Property class to check + size_t *nprops; OUT: Number of properties in the property list + hbool_t recurse; IN: Include properties in parent class(es) also + RETURNS + Success: non-negative value (can't fail) + Failure: negative value + DESCRIPTION + This routine retrieves the number of a properties in a property class. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, hbool_t recurse) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_get_nprops_pclass, FAIL) + + HDassert(pclass); + HDassert(nprops); + + /* Get number of properties */ + *nprops = pclass->nprops; + + /* Check if the class is derived, and walk up the chain, if so */ + if(recurse) + while(pclass->parent != NULL) { + pclass = pclass->parent; + *nprops += pclass->nprops; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P_get_nprops_pclass() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_cmp_prop + PURPOSE + Internal routine to compare two generic properties + USAGE + int H5P_cmp_prop(prop1, prop2) + H5P_genprop_t *prop1; IN: 1st property to compare + H5P_genprop_t *prop1; IN: 2nd property to compare + RETURNS + Success: negative if prop1 "less" than prop2, positive if prop1 "greater" + than prop2, zero if prop1 is "equal" to prop2 + Failure: can't fail + DESCRIPTION + This function compares two generic properties together to see if + they are the same property. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2) +{ + int cmp_value; /* Value from comparison */ + int ret_value = 0; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_prop); + + HDassert(prop1); + HDassert(prop2); + + /* Check the name */ + if((cmp_value = HDstrcmp(prop1->name, prop2->name)) != 0) + HGOTO_DONE(cmp_value); + + /* Check the size of properties */ + if(prop1->size < prop2->size) HGOTO_DONE(-1); + if(prop1->size > prop2->size) HGOTO_DONE(1); + + /* Check if they both have the same 'create' callback */ + if(prop1->create == NULL && prop2->create != NULL) HGOTO_DONE(-1); + if(prop1->create != NULL && prop2->create == NULL) HGOTO_DONE(1); + if(prop1->create != prop2->create) HGOTO_DONE(-1); + + /* Check if they both have the same 'set' callback */ + if(prop1->set == NULL && prop2->set != NULL) HGOTO_DONE(-1); + if(prop1->set != NULL && prop2->set == NULL) HGOTO_DONE(1); + if(prop1->set != prop2->set) HGOTO_DONE(-1); + + /* Check if they both have the same 'get' callback */ + if(prop1->get == NULL && prop2->get != NULL) HGOTO_DONE(-1); + if(prop1->get != NULL && prop2->get == NULL) HGOTO_DONE(1); + if(prop1->get != prop2->get) HGOTO_DONE(-1); + + /* Check if they both have the same 'delete' callback */ + if(prop1->del == NULL && prop2->del != NULL) HGOTO_DONE(-1); + if(prop1->del != NULL && prop2->del == NULL) HGOTO_DONE(1); + if(prop1->del != prop2->del) HGOTO_DONE(-1); + + /* Check if they both have the same 'copy' callback */ + if(prop1->copy == NULL && prop2->copy != NULL) HGOTO_DONE(-1); + if(prop1->copy != NULL && prop2->copy == NULL) HGOTO_DONE(1); + if(prop1->copy != prop2->copy) HGOTO_DONE(-1); + + /* Check if they both have the same 'compare' callback */ + if(prop1->cmp == NULL && prop2->cmp != NULL) HGOTO_DONE(-1); + if(prop1->cmp != NULL && prop2->cmp == NULL) HGOTO_DONE(1); + if(prop1->cmp != prop2->cmp) HGOTO_DONE(-1); + + /* Check if they both have the same 'close' callback */ + if(prop1->close == NULL && prop2->close != NULL) HGOTO_DONE(-1); + if(prop1->close != NULL && prop2->close == NULL) HGOTO_DONE(1); + if(prop1->close != prop2->close) HGOTO_DONE(-1); + + /* Check if they both have values allocated (or not allocated) */ + if(prop1->value == NULL && prop2->value != NULL) HGOTO_DONE(-1); + if(prop1->value != NULL && prop2->value == NULL) HGOTO_DONE(1); + if(prop1->value != NULL) { + /* Call comparison routine */ + if((cmp_value = prop1->cmp(prop1->value, prop2->value, prop1->size)) != 0) + HGOTO_DONE(cmp_value); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_cmp_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_cmp_class + PURPOSE + Internal routine to compare two generic property classes + USAGE + int H5P_cmp_class(pclass1, pclass2) + H5P_genclass_t *pclass1; IN: 1st property class to compare + H5P_genclass_t *pclass2; IN: 2nd property class to compare + RETURNS + Success: negative if class1 "less" than class2, positive if class1 "greater" + than class2, zero if class1 is "equal" to class2 + Failure: can't fail + DESCRIPTION + This function compares two generic property classes together to see if + they are the same class. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5P_cmp_class(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2) +{ + H5SL_node_t *tnode1, *tnode2; /* Temporary pointer to property nodes */ + int cmp_value; /* Value from comparison */ + int ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_class); + + HDassert(pclass1); + HDassert(pclass2); + + /* Use the revision number to quickly check for identical classes */ + if(pclass1->revision == pclass2->revision) + HGOTO_DONE(0); + + /* Check the name */ + if((cmp_value = HDstrcmp(pclass1->name, pclass2->name)) != 0) + HGOTO_DONE(cmp_value); + + /* Check the number of properties */ + if(pclass1->nprops < pclass2->nprops) HGOTO_DONE(-1); + if(pclass1->nprops > pclass2->nprops) HGOTO_DONE(1); + + /* Check the number of property lists created from the class */ + if(pclass1->plists < pclass2->plists) HGOTO_DONE(-1); + if(pclass1->plists > pclass2->plists) HGOTO_DONE(1); + + /* Check the number of classes derived from the class */ + if(pclass1->classes < pclass2->classes) HGOTO_DONE(-1); + if(pclass1->classes > pclass2->classes) HGOTO_DONE(1); + + /* Check the number of ID references open on the class */ + if(pclass1->ref_count < pclass2->ref_count) HGOTO_DONE(-1); + if(pclass1->ref_count > pclass2->ref_count) HGOTO_DONE(1); + + /* Check whether they are internal or not */ + if(pclass1->internal < pclass2->internal) HGOTO_DONE(-1); + if(pclass1->internal > pclass2->internal) HGOTO_DONE(1); + + /* Check whether they are deleted or not */ + if(pclass1->deleted < pclass2->deleted) HGOTO_DONE(-1); + if(pclass1->deleted > pclass2->deleted) HGOTO_DONE(1); + + /* Check whether they have creation callback functions & data */ + if(pclass1->create_func == NULL && pclass2->create_func != NULL) HGOTO_DONE(-1); + if(pclass1->create_func != NULL && pclass2->create_func == NULL) HGOTO_DONE(1); + if(pclass1->create_func != pclass2->create_func) HGOTO_DONE(-1); + if(pclass1->create_data < pclass2->create_data) HGOTO_DONE(-1); + if(pclass1->create_data > pclass2->create_data) HGOTO_DONE(1); + + /* Check whether they have close callback functions & data */ + if(pclass1->close_func == NULL && pclass2->close_func != NULL) HGOTO_DONE(-1); + if(pclass1->close_func != NULL && pclass2->close_func == NULL) HGOTO_DONE(1); + if(pclass1->close_func != pclass2->close_func) HGOTO_DONE(-1); + if(pclass1->close_data < pclass2->close_data) HGOTO_DONE(-1); + if(pclass1->close_data > pclass2->close_data) HGOTO_DONE(1); + + /* Cycle through the properties and compare them also */ + tnode1 = H5SL_first(pclass1->props); + tnode2 = H5SL_first(pclass2->props); + while(tnode1 || tnode2) { + H5P_genprop_t *prop1, *prop2; /* Property for node */ + + /* Check if they both have properties in this skip list node */ + if(tnode1 == NULL && tnode2 != NULL) HGOTO_DONE(-1); + if(tnode1 != NULL && tnode2 == NULL) HGOTO_DONE(1); + + /* Compare the two properties */ + prop1 = H5SL_item(tnode1); + prop2 = H5SL_item(tnode2); + if((cmp_value = H5P_cmp_prop(prop1, prop2)) != 0) + HGOTO_DONE(cmp_value); + + /* Advance the pointers */ + tnode1 = H5SL_next(tnode1); + tnode2 = H5SL_next(tnode2); + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_cmp_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_cmp_plist + PURPOSE + Internal routine to compare two generic property lists + USAGE + int H5P_cmp_plist(plist1, plist2) + H5P_genplist_t *plist1; IN: 1st property list to compare + H5P_genplist_t *plist2; IN: 2nd property list to compare + RETURNS + Success: negative if list1 "less" than list2, positive if list1 "greater" + than list2, zero if list1 is "equal" to list2 + Failure: can't fail + DESCRIPTION + This function compares two generic property lists together to see if + they are the same list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5P_cmp_plist(const H5P_genplist_t *plist1, const H5P_genplist_t *plist2) +{ + H5SL_node_t *tnode1, *tnode2; /* Temporary pointer to property nodes */ + int cmp_value; /* Value from comparison */ + int ret_value = 0; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_cmp_plist); + + HDassert(plist1); + HDassert(plist2); + + /* Check the number of properties */ + if(plist1->nprops < plist2->nprops) HGOTO_DONE(-1); + if(plist1->nprops > plist2->nprops) HGOTO_DONE(1); + + /* Check whether they've been initialized */ + if(plist1->class_init < plist2->class_init) HGOTO_DONE(-1); + if(plist1->class_init > plist2->class_init) HGOTO_DONE(1); + + /* Check for identical deleted properties */ + if(H5SL_count(plist1->del) > 0) { + /* Check for no deleted properties in plist2 */ + if(H5SL_count(plist2->del) == 0) HGOTO_DONE(1); + + tnode1 = H5SL_first(plist1->del); + tnode2 = H5SL_first(plist2->del); + while(tnode1 || tnode2) { + const char *name1, *name2; /* Name for node */ + + /* Check if they both have properties in this node */ + if(tnode1 == NULL && tnode2 != NULL) HGOTO_DONE(-1); + if(tnode1 != NULL && tnode2 == NULL) HGOTO_DONE(1); + + /* Compare the two deleted properties */ + name1 = H5SL_item(tnode1); + name2 = H5SL_item(tnode2); + if((cmp_value = HDstrcmp(name1, name2)) != 0) + HGOTO_DONE(cmp_value); + + /* Advance the pointers */ + tnode1 = H5SL_next(tnode1); + tnode2 = H5SL_next(tnode2); + } /* end while */ + } /* end if */ + else + if(H5SL_count(plist2->del) > 0) HGOTO_DONE (-1); + + /* Cycle through the changed properties and compare them also */ + if(H5SL_count(plist1->props) > 0) { + /* Check for no changed properties in plist2 */ + if(H5SL_count(plist2->props) == 0) HGOTO_DONE(1); + + tnode1 = H5SL_first(plist1->props); + tnode2 = H5SL_first(plist2->props); + while(tnode1 || tnode2) { + H5P_genprop_t *prop1, *prop2; /* Property for node */ + + /* Check if they both have properties in this node */ + if(tnode1 == NULL && tnode2 != NULL) HGOTO_DONE(-1); + if(tnode1 != NULL && tnode2 == NULL) HGOTO_DONE(1); + + /* Compare the two properties */ + prop1 = H5SL_item(tnode1); + prop2 = H5SL_item(tnode2); + if((cmp_value = H5P_cmp_prop(prop1, prop2)) != 0) + HGOTO_DONE(cmp_value); + + /* Advance the pointers */ + tnode1 = H5SL_next(tnode1); + tnode2 = H5SL_next(tnode2); + } /* end while */ + } /* end if */ + else + if(H5SL_count(plist2->props)>0) HGOTO_DONE (-1); + + /* Check the parent classes */ + if((cmp_value = H5P_cmp_class(plist1->pclass, plist2->pclass)) != 0) + HGOTO_DONE(cmp_value); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_cmp_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_isa_class_real + PURPOSE + Internal routine to query whether a property class is the same as another + class. + USAGE + htri_t H5P_isa_class_real(pclass1, pclass2) + H5P_genclass_t *pclass1; IN: Property class to check + H5P_genclass_t *pclass2; IN: Property class to compare with + RETURNS + Success: TRUE (1) or FALSE (0) + Failure: negative value + DESCRIPTION + This routine queries whether a property class is the same as another class, + and walks up the hierarchy of derived classes, checking if the first class + is derived from the second class also. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5P_isa_class_real(H5P_genclass_t *pclass1, H5P_genclass_t *pclass2) +{ + htri_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_isa_class_real); + + assert(pclass1); + assert(pclass2); + + /* Compare property classes */ + if(H5P_cmp_class(pclass1, pclass2) == 0) { + HGOTO_DONE(TRUE); + } else { + /* Check if the class is derived, and walk up the chain, if so */ + if(pclass1->parent != NULL) + ret_value = H5P_isa_class_real(pclass1->parent, pclass2); + else + HGOTO_DONE(FALSE); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_isa_class_real() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_isa_class + PURPOSE + Internal routine to query whether a property list is a certain class + USAGE + hid_t H5P_isa_class(plist_id, pclass_id) + hid_t plist_id; IN: Property list to query + hid_t pclass_id; IN: Property class to query + RETURNS + Success: TRUE (1) or FALSE (0) + Failure: negative + DESCRIPTION + This routine queries whether a property list is a member of the property + list class. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + This function is special in that it is an internal library function, but + accepts hid_t's as parameters. Since it is used in basically the same way + as the H5I functions, this should be OK. Don't make more library functions + which accept hid_t's without thorough discussion. -QAK + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5P_isa_class(hid_t plist_id, hid_t pclass_id) +{ + H5P_genplist_t *plist; /* Property list to query */ + H5P_genclass_t *pclass; /* Property list class */ + htri_t ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_isa_class, FAIL); + + /* Check arguments. */ + if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); + + /* Compare the property list's class against the other class */ + if((ret_value = H5P_isa_class_real(plist->pclass, pclass)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to compare property list classes"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_isa_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_object_verify + PURPOSE + Internal routine to query whether a property list is a certain class and + retrieve the property list object associated with it. + USAGE + void *H5P_object_verify(plist_id, pclass_id) + hid_t plist_id; IN: Property list to query + hid_t pclass_id; IN: Property class to query + RETURNS + Success: valid pointer to a property list object + Failure: NULL + DESCRIPTION + This routine queries whether a property list is member of a certain class + and retrieves the property list object associated with it. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + This function is special in that it is an internal library function, but + accepts hid_t's as parameters. Since it is used in basically the same way + as the H5I functions, this should be OK. Don't make more library functions + which accept hid_t's without thorough discussion. -QAK + + This function is similar (in spirit) to H5I_object_verify() + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +void * +H5P_object_verify(hid_t plist_id, hid_t pclass_id) +{ + void *ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_object_verify, NULL); + + /* Compare the property list's class against the other class */ + if(H5P_isa_class(plist_id, pclass_id) != TRUE) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, NULL, "property list is not a member of the class"); + + /* Get the plist structure */ + if(NULL == (ret_value = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_object_verify() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_iterate_plist + PURPOSE + Internal routine to iterate over the properties in a property list + USAGE + herr_t H5P_iterate_plist(plist_id, idx, iter_func, iter_data) + hid_t plist_id; IN: ID of property list to iterate over + int *idx; IN/OUT: Index of the property to begin with + H5P_iterate_t iter_func; IN: Function pointer to function to be + called with each property iterated over. + void *iter_data; IN/OUT: Pointer to iteration data from user + RETURNS + Success: Returns the return value of the last call to ITER_FUNC if it was + non-zero, or zero if all properties have been processed. + Failure: negative value + DESCRIPTION + This routine iterates over the properties in the property object specified +with PLIST_ID. For each property in the object, the ITER_DATA and some +additional information, specified below, are passed to the ITER_FUNC function. +The iteration begins with the IDX property in the object and the next element +to be processed by the operator is returned in IDX. If IDX is NULL, then the +iterator starts at the first property; since no stopping point is returned in +this case, the iterator cannot be restarted if one of the calls to its operator +returns non-zero. + +The prototype for H5P_iterate_t is: + typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); +The operation receives the property list or class identifier for the object +being iterated over, ID, the name of the current property within the object, +NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA. + +The return values from an operator are: + Zero causes the iterator to continue, returning zero when all properties + have been processed. + Positive causes the iterator to immediately return that positive value, + indicating short-circuit success. The iterator can be restarted at the + index of the next property. + Negative causes the iterator to immediately return that value, indicating + failure. The iterator can be restarted at the index of the next + property. + +H5Piterate assumes that the properties in the object identified by ID remains +unchanged through the iteration. If the membership changes during the +iteration, the function's behavior is undefined. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_data) +{ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genplist_t *plist; /* Property list pointer */ + H5P_genprop_t *tmp; /* Temporary pointer to properties */ + H5SL_t *seen = NULL; /* Skip list to hold names of properties already seen */ + H5SL_node_t *curr_node; /* Current node in skip list */ + int curr_idx = 0; /* Current iteration index */ + int ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_plist); + + HDassert(idx); + HDassert(iter_func); + + /* Get the property list object */ + if(NULL == (plist = H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + + /* Create the skip list to hold names of properties already seen */ + if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); + + /* Walk through the changed properties in the list */ + if(H5SL_count(plist->props) > 0) { + curr_node = H5SL_first(plist->props); + while(curr_node != NULL) { + /* Get pointer to property from node */ + tmp = H5SL_item(curr_node); + + /* Check if we've found the correctly indexed property */ + if(curr_idx>=*idx) { + /* Call the callback function */ + ret_value=(*iter_func)(plist_id,tmp->name,iter_data); + + if(ret_value!=0) + HGOTO_DONE(ret_value); + } /* end if */ + + /* Increment the current index */ + curr_idx++; + + /* Add property name to "seen" list */ + if(H5SL_insert(seen,tmp->name,tmp->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Walk up the class hiearchy */ + tclass=plist->pclass; + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Walk through the properties in the class */ + curr_node=H5SL_first(tclass->props); + while(curr_node!=NULL) { + /* Get pointer to property from node */ + tmp=H5SL_item(curr_node); + + /* Only call iterator callback for properties we haven't seen + * before and that haven't been deleted + */ + if(H5SL_search(seen,tmp->name) == NULL && + H5SL_search(plist->del,tmp->name) == NULL) { + + + /* Check if we've found the correctly indexed property */ + if(curr_idx>=*idx) { + /* Call the callback function */ + ret_value=(*iter_func)(plist_id,tmp->name,iter_data); + + if(ret_value!=0) + HGOTO_DONE(ret_value); + } /* end if */ + + /* Increment the current index */ + curr_idx++; + + /* Add property name to "seen" list */ + if(H5SL_insert(seen,tmp->name,tmp->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + } /* end if */ + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + +done: + /* Set the index we stopped at */ + *idx=curr_idx; + + /* Release the skip list of 'seen' properties */ + if(seen!=NULL) + H5SL_close(seen); + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_iterate_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_iterate_pclass + PURPOSE + Internal routine to iterate over the properties in a property class + USAGE + herr_t H5P_iterate_pclass(pclass_id, idx, iter_func, iter_data) + hid_t pclass_id; IN: ID of property class to iterate over + int *idx; IN/OUT: Index of the property to begin with + H5P_iterate_t iter_func; IN: Function pointer to function to be + called with each property iterated over. + void *iter_data; IN/OUT: Pointer to iteration data from user + RETURNS + Success: Returns the return value of the last call to ITER_FUNC if it was + non-zero, or zero if all properties have been processed. + Failure: negative value + DESCRIPTION + This routine iterates over the properties in the property object specified +with PCLASS_ID. For each property in the object, the ITER_DATA and some +additional information, specified below, are passed to the ITER_FUNC function. +The iteration begins with the IDX property in the object and the next element +to be processed by the operator is returned in IDX. If IDX is NULL, then the +iterator starts at the first property; since no stopping point is returned in +this case, the iterator cannot be restarted if one of the calls to its operator +returns non-zero. + +The prototype for H5P_iterate_t is: + typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); +The operation receives the property list or class identifier for the object +being iterated over, ID, the name of the current property within the object, +NAME, and the pointer to the operator data passed in to H5Piterate, ITER_DATA. + +The return values from an operator are: + Zero causes the iterator to continue, returning zero when all properties + have been processed. + Positive causes the iterator to immediately return that positive value, + indicating short-circuit success. The iterator can be restarted at the + index of the next property. + Negative causes the iterator to immediately return that value, indicating + failure. The iterator can be restarted at the index of the next + property. + +H5Piterate assumes that the properties in the object identified by ID remains +unchanged through the iteration. If the membership changes during the +iteration, the function's behavior is undefined. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, void *iter_data) +{ + H5P_genclass_t *pclass; /* Property list pointer */ + H5SL_node_t *curr_node; /* Current node in skip list */ + H5P_genprop_t *prop; /* Temporary property pointer */ + int curr_idx=0; /* Current iteration index */ + int ret_value=FAIL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_iterate_pclass); + + assert(idx); + assert(iter_func); + + /* Get the property list object */ + if(NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property class"); + + /* Cycle through the properties and call the callback */ + curr_idx=0; + curr_node=H5SL_first(pclass->props); + while(curr_node!=NULL) { + if(curr_idx>=*idx) { + /* Get the property for the node */ + prop=H5SL_item(curr_node); + + /* Call the callback function */ + ret_value=(*iter_func)(pclass_id,prop->name,iter_data); + + /* Check if iteration function succeeded */ + if(ret_value!=0) + HGOTO_DONE(ret_value); + } /* end if */ + + /* Increment the iteration index */ + curr_idx++; + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + +done: + /* Set the index we stopped at */ + *idx=curr_idx; + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_iterate_pclass() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_peek_unsigned + PURPOSE + Internal routine to quickly retrieve the value of a property in a property list. + USAGE + int H5P_peek_unsigned(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + RETURNS + Directly returns the value of the property in the list + DESCRIPTION + This function directly returns the value of a property in a property + list. Because this function is only able to just copy a particular property + value to the return value, there is no way to check for errors. We attempt + to make certain that bad things don't happen by validating that the size of + the property is the same as the size of the return type, but that can't + catch all errors. + This function does call the user's 'get' callback routine still. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + No error checking! + Use with caution! + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +unsigned +H5P_peek_unsigned(H5P_genplist_t *plist, const char *name) +{ + unsigned ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_peek_unsigned, UFAIL); + + assert(plist); + assert(name); + + /* Get the value to return, don't worry about the return value, we can't return it */ + H5P_get(plist,name,&ret_value); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_peek_unsigned() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_peek_hid_t + PURPOSE + Internal routine to quickly retrieve the value of a property in a property list. + USAGE + hid_t H5P_peek_hid_t(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + RETURNS + Directly returns the value of the property in the list + DESCRIPTION + This function directly returns the value of a property in a property + list. Because this function is only able to just copy a particular property + value to the return value, there is no way to check for errors. We attempt + to make certain that bad things don't happen by validating that the size of + the property is the same as the size of the return type, but that can't + catch all errors. + This function does call the user's 'get' callback routine still. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + No error checking! + Use with caution! + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hid_t +H5P_peek_hid_t(H5P_genplist_t *plist, const char *name) +{ + hid_t ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_peek_hid_t, FAIL); + + assert(plist); + assert(name); + + /* Get the value to return, don't worry about the return value, we can't return it */ + H5P_get(plist,name,&ret_value); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_peek_hid_t() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_peek_voidp + PURPOSE + Internal routine to quickly retrieve the value of a property in a property list. + USAGE + void *H5P_peek_voidp(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + RETURNS + Directly returns the value of the property in the list + DESCRIPTION + This function directly returns the value of a property in a property + list. Because this function is only able to just copy a particular property + value to the return value, there is no way to check for errors. We attempt + to make certain that bad things don't happen by validating that the size of + the property is the same as the size of the return type, but that can't + catch all errors. + This function does call the user's 'get' callback routine still. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + No error checking! + Use with caution! + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +void * +H5P_peek_voidp(H5P_genplist_t *plist, const char *name) +{ + void * ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_peek_voidp, NULL); + + assert(plist); + assert(name); + + /* Get the value to return, don't worry about the return value, we can't return it */ + H5P_get(plist,name,&ret_value); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_peek_voidp() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_peek_size_t + PURPOSE + Internal routine to quickly retrieve the value of a property in a property list. + USAGE + hsize_t H5P_peek_size_t(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + RETURNS + Directly returns the value of the property in the list + DESCRIPTION + This function directly returns the value of a property in a property + list. Because this function is only able to just copy a particular property + value to the return value, there is no way to check for errors. We attempt + to make certain that bad things don't happen by validating that the size of + the property is the same as the size of the return type, but that can't + catch all errors. + This function does call the user's 'get' callback routine still. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + No error checking! + Use with caution! + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +size_t +H5P_peek_size_t(H5P_genplist_t *plist, const char *name) +{ + size_t ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_peek_size_t, UFAIL); + + assert(plist); + assert(name); + + /* Get the value to return, don't worry about the return value, we can't return it */ + H5P_get(plist,name,&ret_value); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_peek_size_t() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get + PURPOSE + Internal routine to query the value of a property in a property list. + USAGE + herr_t H5P_get(plist, name, value) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + void *value; OUT: Pointer to the buffer for the property value + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Retrieves a copy of the value for a property in a property list. The + property name must exist or this routine will fail. If there is a + 'get' callback routine registered for this property, the copy of the + value of the property will first be passed to that routine and any changes + to the copy of the value will be used when returning the property value + from this routine. + If the 'get' callback routine returns an error, 'value' will not be + modified and this routine will return an error. This routine may not be + called for zero-sized properties. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_get(H5P_genplist_t *plist, const char *name, void *value) +{ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_get, FAIL); + + assert(plist); + assert(name); + assert(value); + + /* Check if the property has been deleted */ + if(H5SL_search(plist->del,name)!=NULL) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist"); + + /* Find property */ + if((prop=H5SL_search(plist->props,name))!=NULL) { + /* Check for property size >0 */ + if(prop->size==0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size"); + + /* Make a copy of the value and pass to 'get' callback */ + if(prop->get!=NULL) { + void *tmp_value; /* Temporary value for property */ + + /* Make a copy of the current value, in case the callback fails */ + if(NULL==(tmp_value=H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HDmemcpy(tmp_value,prop->value,prop->size); + + /* Call user's callback */ + if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value"); + + /* Copy new [possibly unchanged] value into return value */ + HDmemcpy(value,tmp_value,prop->size); + + /* Free the temporary value buffer */ + H5MM_xfree(tmp_value); + } /* end if */ + /* No 'get' callback, just copy value */ + else + HDmemcpy(value,prop->value,prop->size); + } /* end if */ + else { + /* + * Check if we should get class properties (up through list of parent classes also), + * & make property 'get' callback. + */ + tclass=plist->pclass; + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Find the property in the class */ + if((prop=H5SL_search(tclass->props,name))!=NULL) { + /* Check for property size >0 */ + if(prop->size==0) + HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size"); + + /* Call the 'get' callback, if there is one */ + if(prop->get!=NULL) { + void *tmp_value; /* Temporary value for property */ + + /* Make a copy of the current value, in case the callback fails */ + if(NULL==(tmp_value=H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value"); + HDmemcpy(tmp_value,prop->value,prop->size); + + /* Call user's callback */ + if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value) < 0) { + H5MM_xfree(tmp_value); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value"); + } /* end if */ + + if(HDmemcmp(tmp_value,prop->value,prop->size)) { + H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */ + + /* Make a copy of the class's property */ + if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property"); + + /* Copy new value into property value */ + HDmemcpy(pcopy->value,tmp_value,prop->size); + + /* Insert the changed property into the property list */ + if(H5P_add_prop(plist->props,pcopy) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list"); + } /* end if */ + + /* Copy new [possibly unchanged] value into return value */ + HDmemcpy(value,tmp_value,prop->size); + + /* Free the temporary value buffer */ + H5MM_xfree(tmp_value); + } /* end if */ + /* No 'get' callback, just copy value */ + else + HDmemcpy(value,prop->value,prop->size); + + /* Leave */ + HGOTO_DONE(SUCCEED); + } /* end while */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* If we get this far, then it wasn't in the list of changed properties, + * nor in the properties in the class hierarchy, indicate an error + */ + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_get() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_remove + PURPOSE + Internal routine to remove a property from a property list. + USAGE + herr_t H5P_remove(plist, name) + H5P_genplist_t *plist; IN: Property list to modify + const char *name; IN: Name of property to remove + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Removes a property from a property list. Both properties which were + in existance when the property list was created (i.e. properties registered + with H5Pregister2) and properties added to the list after it was created + (i.e. added with H5Pinsert) may be removed from a property list. + Properties do not need to be removed a property list before the list itself + is closed, they will be released automatically when H5Pclose is called. + The 'close' callback for this property is called before the property is + release, if the callback exists. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) +{ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genprop_t *prop; /* Temporary property pointer */ + char *del_name; /* Pointer to deleted name */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_remove,FAIL); + + assert(plist); + assert(name); + + /* Indicate that the property isn't in the list if it has been deleted already */ + if(H5SL_search(plist->del,name)!=NULL) + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + + /* Get the property node from the changed property skip list */ + if((prop=H5SL_search(plist->props,name))!=NULL) { + /* Pass value to 'close' callback, if it exists */ + if(prop->del!=NULL) { + /* Call user's callback */ + if((*(prop->del))(plist_id,name,prop->size,prop->value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value"); + } /* end if */ + + /* Duplicate string for insertion into new deleted property skip list */ + if((del_name=H5MM_xstrdup(name)) == NULL) + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); + + /* Insert property name into deleted list */ + if(H5SL_insert(plist->del,del_name,del_name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); + + /* Remove the property from the skip list */ + if(H5SL_remove(plist->props,prop->name) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list"); + + /* Free the property, ignoring return value, nothing we can do */ + H5P_free_prop(prop); + + /* Decrement the number of properties in list */ + plist->nprops--; + } /* end if */ + /* Walk through all the properties in the class hierarchy, looking for the property */ + else { + /* + * Check if we should delete class properties (up through list of parent classes also), + * & make property 'delete' callback. + */ + tclass=plist->pclass; + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Find the property in the class */ + if((prop=H5P_find_prop_pclass(tclass,name))!=NULL) { + /* Pass value to 'del' callback, if it exists */ + if(prop->del!=NULL) { + void *tmp_value; /* Temporary value buffer */ + + /* Allocate space for a temporary copy of the property value */ + if(NULL==(tmp_value=H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); + HDmemcpy(tmp_value,prop->value,prop->size); + + /* Call user's callback */ + if((*(prop->del))(plist_id,name,prop->size,tmp_value) < 0) { + H5MM_xfree(tmp_value); + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value"); + } /* end if */ + + /* Release the temporary value buffer */ + H5MM_xfree(tmp_value); + } /* end if */ + + /* Duplicate string for insertion into new deleted property skip list */ + if((del_name=H5MM_xstrdup(name)) == NULL) + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed"); + + /* Insert property name into deleted list */ + if(H5SL_insert(plist->del,del_name,del_name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list"); + + /* Decrement the number of properties in list */ + plist->nprops--; + + /* Leave */ + HGOTO_DONE(SUCCEED); + } /* end while */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* If we get this far, then it wasn't in the list of changed properties, + * nor in the properties in the class hierarchy, indicate an error + */ + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_remove() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_copy_prop_plist + PURPOSE + Internal routine to copy a property from one list to another + USAGE + herr_t H5P_copy_prop_plist(dst_plist, src_plist, name) + hid_t dst_id; IN: ID of destination property list or class + hid_t src_id; IN: ID of source property list or class + const char *name; IN: Name of property to copy + RETURNS + Success: non-negative value. + Failure: negative value. + DESCRIPTION + Copies a property from one property list to another. + + If a property is copied from one list to another, the property will be + first deleted from the destination list (generating a call to the 'close' + callback for the property, if one exists) and then the property is copied + from the source list to the destination list (generating a call to the + 'copy' callback for the property, if one exists). + + If the property does not exist in the destination list, this call is + equivalent to calling H5Pinsert and the 'create' callback will be called + (if such a callback exists for the property). + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) +{ + H5P_genplist_t *dst_plist; /* Pointer to destination property list */ + H5P_genplist_t *src_plist; /* Pointer to source property list */ + H5P_genprop_t *prop; /* Temporary property pointer */ + H5P_genprop_t *new_prop=NULL; /* Pointer to new property */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_plist); + + assert(name); + + /* Get the objects to operate on */ + if(NULL == (src_plist = H5I_object(src_id)) || NULL == (dst_plist = H5I_object(dst_id))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property object doesn't exist"); + + /* If the property exists in the destination alread */ + if(H5P_find_prop_plist(dst_plist,name)!=NULL) { + /* Delete the property from the destination list, calling the 'close' callback if necessary */ + if(H5P_remove(dst_id,dst_plist,name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + + /* Get the pointer to the source property */ + prop=H5P_find_prop_plist(src_plist,name); + + /* Make a copy of the source property */ + if((new_prop=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + + /* Call property copy callback, if it exists */ + if(new_prop->copy) { + if((new_prop->copy)(new_prop->name,new_prop->size,new_prop->value) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + } /* end if */ + + /* Insert the initialized property into the property list */ + if(H5P_add_prop(dst_plist->props,new_prop) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into list"); + + /* Increment the number of properties in list */ + dst_plist->nprops++; + } /* end if */ + /* If not, get the information required to do an H5Pinsert with the property into the destination list */ + else { + /* Get the pointer to the source property */ + prop=H5P_find_prop_plist(src_plist,name); + + /* Create property object from parameters */ + if((new_prop=H5P_create_prop(prop->name,prop->size,H5P_PROP_WITHIN_LIST,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCREATE, FAIL,"Can't create property"); + + /* Call property creation callback, if it exists */ + if(new_prop->create) { + if((new_prop->create)(new_prop->name,new_prop->size,new_prop->value) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); + } /* end if */ + + /* Insert property into property list class */ + if(H5P_add_prop(dst_plist->props,new_prop) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + + /* Increment property count for class */ + dst_plist->nprops++; + + } /* end else */ + +done: + /* Cleanup, if necessary */ + if(ret_value<0) { + if(new_prop!=NULL) + H5P_free_prop(new_prop); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_copy_prop_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_copy_prop_pclass + PURPOSE + Internal routine to copy a property from one class to another + USAGE + herr_t H5P_copy_prop_pclass(dst_pclass, src_pclass, name) + H5P_genclass_t *dst_pclass; IN: Pointer to destination class + H5P_genclass_t *src_pclass; IN: Pointer to source class + const char *name; IN: Name of property to copy + RETURNS + Success: non-negative value. + Failure: negative value. + DESCRIPTION + Copies a property from one property class to another. + + If a property is copied from one class to another, all the property + information will be first deleted from the destination class and then the + property information will be copied from the source class into the + destination class. + + If the property does not exist in the destination class or list, this call + is equivalent to calling H5Pregister2. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, const char *name) +{ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_copy_prop_pclass); + + assert(dst_pclass); + assert(src_pclass); + assert(name); + + /* If the property exists in the destination already */ + if(H5P_exist_pclass(dst_pclass,name)) { + /* Delete the old property from the destination class */ + if(H5P_unregister(dst_pclass,name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + } /* end if */ + + /* Get the property from the source */ + if((prop=H5P_find_prop_pclass(src_pclass,name)) == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to locate property"); + + /* Register the property into the destination */ + if(H5P_register(dst_pclass,name,prop->size,prop->value,prop->create,prop->set,prop->get,prop->del,prop->copy,prop->cmp,prop->close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property"); + +done: + /* Cleanup, if necessary */ + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_copy_prop_pclass() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_unregister + PURPOSE + Internal routine to remove a property from a property list class. + USAGE + herr_t H5P_unregister(pclass, name) + H5P_genclass_t *pclass; IN: Property list class to modify + const char *name; IN: Name of property to remove + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Removes a property from a property list class. Future property lists + created of that class will not contain this property. Existing property + lists containing this property are not affected. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_unregister(H5P_genclass_t *pclass, const char *name) +{ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_unregister); + + assert(pclass); + assert(name); + + /* Get the property node from the skip list */ + if((prop=H5SL_search(pclass->props,name)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list"); + + /* Remove the property from the skip list */ + if(H5SL_remove(pclass->props,prop->name) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list"); + + /* Free the property, ignoring return value, nothing we can do */ + H5P_free_prop(prop); + + /* Decrement the number of registered properties in class */ + pclass->nprops--; + + /* Update the revision for the class */ + pclass->revision = H5P_GET_NEXT_REV; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_unregister() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_close + PURPOSE + Internal routine to close a property list. + USAGE + herr_t H5P_close(plist) + H5P_genplist_t *plist; IN: Property list to close + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Closes a property list. If a 'close' callback exists for the property + list class, it is called before the property list is destroyed. If 'close' + callbacks exist for any individual properties in the property list, they are + called after the class 'close' callback. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The property list class 'close' callback routine is not called from + here, it must have been check for and called properly prior to this routine + being called + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_close(void *_plist) +{ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5P_genplist_t *plist=(H5P_genplist_t *)_plist; + H5SL_t *seen=NULL; /* Skip list to hold names of properties already seen */ + size_t nseen; /* Number of items 'seen' */ + hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */ + size_t ndel; /* Number of items deleted */ + H5SL_node_t *curr_node; /* Current node in skip list */ + H5P_genprop_t *tmp; /* Temporary pointer to properties */ + unsigned make_cb=0; /* Operator data for property free callback */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_close); + + assert(plist); + + /* Make call to property list class close callback, if needed */ + if(plist->class_init!=0 && plist->pclass->close_func!=NULL) { + /* Call user's "close" callback function, ignoring return value */ + (plist->pclass->close_func)(plist->plist_id,plist->pclass->close_data); + } /* end if */ + + /* Create the skip list to hold names of properties already seen + * (This prevents a property in the class hierarchy from having it's + * 'close' callback called, if a property in the class hierarchy has + * already been seen) + */ + if((seen = H5SL_create(H5SL_TYPE_STR, 0.5, (size_t)H5P_DEFAULT_SKIPLIST_HEIGHT)) == NULL) + HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties"); + nseen = 0; + + /* Walk through the changed properties in the list */ + if(H5SL_count(plist->props)>0) { + curr_node=H5SL_first(plist->props); + while(curr_node!=NULL) { + /* Get pointer to property from node */ + tmp=H5SL_item(curr_node); + + /* Call property close callback, if it exists */ + if(tmp->close) { + /* Call the 'close' callback */ + (tmp->close)(tmp->name,tmp->size,tmp->value); + } /* end if */ + + /* Add property name to "seen" list */ + if(H5SL_insert(seen,tmp->name,tmp->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + nseen++; + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Determine number of deleted items from property list */ + ndel=H5SL_count(plist->del); + + /* + * Check if we should remove class properties (up through list of parent classes also), + * initialize each with default value & make property 'remove' callback. + */ + tclass=plist->pclass; + has_parent_class=(tclass!=NULL && tclass->parent!=NULL && tclass->parent->nprops>0); + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Walk through the properties in the class */ + curr_node=H5SL_first(tclass->props); + while(curr_node!=NULL) { + /* Get pointer to property from node */ + tmp=H5SL_item(curr_node); + + /* Only "delete" properties we haven't seen before + * and that haven't already been deleted + */ + if((nseen==0 || H5SL_search(seen,tmp->name) == NULL) && + (ndel==0 || H5SL_search(plist->del,tmp->name) == NULL)) { + + /* Call property close callback, if it exists */ + if(tmp->close) { + void *tmp_value; /* Temporary value buffer */ + + /* Allocate space for a temporary copy of the property value */ + if(NULL==(tmp_value=H5MM_malloc(tmp->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value"); + HDmemcpy(tmp_value,tmp->value,tmp->size); + + /* Call the 'close' callback */ + (tmp->close)(tmp->name,tmp->size,tmp_value); + + /* Release the temporary value buffer */ + H5MM_xfree(tmp_value); + } /* end if */ + + /* Add property name to "seen" list, if we have other classes to work on */ + if(has_parent_class) { + if(H5SL_insert(seen,tmp->name,tmp->name) < 0) + HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into seen skip list"); + nseen++; + } /* end if */ + } /* end if */ + + /* Get the next property node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* Decrement class's dependant property list value! */ + if(H5P_access_class(plist->pclass,H5P_MOD_DEC_LST) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count"); + + /* Free the list of 'seen' properties */ + H5SL_close(seen); + seen=NULL; + + /* Free the list of deleted property names */ + H5SL_destroy(plist->del,H5P_free_del_name_cb,NULL); + + /* Free the properties */ + H5SL_destroy(plist->props,H5P_free_prop_cb,&make_cb); + + /* Destroy property list object */ + H5FL_FREE(H5P_genplist_t,plist); + +done: + /* Release the skip list of 'seen' properties */ + if(seen!=NULL) + H5SL_close(seen); + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_close() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_class_name + PURPOSE + Internal routine to query the name of a generic property list class + USAGE + char *H5P_get_class_name(pclass) + H5P_genclass_t *pclass; IN: Property list class to check + RETURNS + Success: Pointer to a malloc'ed string containing the class name + Failure: NULL + DESCRIPTION + This routine retrieves the name of a generic property list class. + The pointer to the name must be free'd by the user for successful calls. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +char * +H5P_get_class_name(H5P_genclass_t *pclass) +{ + char *ret_value; /* return value */ + + FUNC_ENTER_NOAPI(H5P_get_class_name, NULL); + + assert(pclass); + + /* Get class name */ + ret_value=H5MM_xstrdup(pclass->name); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_get_class_name() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_class_path + PURPOSE + Internal routine to query the full path of a generic property list class + USAGE + char *H5P_get_class_name(pclass) + H5P_genclass_t *pclass; IN: Property list class to check + RETURNS + Success: Pointer to a malloc'ed string containing the full path of class + Failure: NULL + DESCRIPTION + This routine retrieves the full path name of a generic property list + class, starting with the root of the class hierarchy. + The pointer to the name must be free'd by the user for successful calls. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +char * +H5P_get_class_path(H5P_genclass_t *pclass) +{ + char *par_path; /* Parent class's full path */ + size_t par_path_len;/* Parent class's full path's length */ + size_t my_path_len; /* This class's name's length */ + char *ret_value; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_get_class_path); + + assert(pclass); + + /* Recursively build the full path */ + if(pclass->parent!=NULL) { + /* Get the parent class's path */ + par_path=H5P_get_class_path(pclass->parent); + if(par_path!=NULL) { + /* Get the string lengths we need to allocate space */ + par_path_len=HDstrlen(par_path); + my_path_len=HDstrlen(pclass->name); + + /* Allocate enough space for the parent class's path, plus the '/' + * separator, this class's name and the string terminator + */ + if(NULL==(ret_value=H5MM_malloc(par_path_len+1+my_path_len+1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for class name"); + + /* Build the full path for this class */ + HDstrcpy(ret_value,par_path); + HDstrcat(ret_value,"/"); + HDstrcat(ret_value,pclass->name); + + /* Free the parent class's path */ + H5MM_xfree(par_path); + } /* end if */ + else + ret_value=H5MM_xstrdup(pclass->name); + } /* end if */ + else + ret_value=H5MM_xstrdup(pclass->name); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_get_class_path() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_open_class_path + PURPOSE + Internal routine to open [a copy of] a class with its full path name + USAGE + H5P_genclass_t *H5P_open_class_path(path) + const char *path; IN: Full path name of class to open [copy of] + RETURNS + Success: Pointer to a generic property class object + Failure: NULL + DESCRIPTION + This routine opens [a copy] of the class indicated by the full path. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5P_genclass_t * +H5P_open_class_path(const char *path) +{ + char *tmp_path=NULL; /* Temporary copy of the path */ + char *curr_name; /* Pointer to current component of path name */ + char *delimit; /* Pointer to path delimiter during traversal */ + H5P_genclass_t *curr_class; /* Pointer to class during path traversal */ + H5P_genclass_t *ret_value; /* Return value */ + H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_open_class_path); + + assert(path); + + /* Duplicate the path to use */ + tmp_path=H5MM_xstrdup(path); + assert(tmp_path); + + /* Find the generic property class with this full path */ + curr_name=tmp_path; + curr_class=NULL; + while((delimit=HDstrchr(curr_name,'/'))!=NULL) { + /* Change the delimiter to terminate the string */ + *delimit='\0'; + + /* Set up the search structure */ + check_info.parent=curr_class; + check_info.name=curr_name; + + /* Find the class with this name & parent by iterating over the open classes */ + if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class"); + + /* Advance the pointer in the path to the start of the next component */ + curr_name=delimit+1; + } /* end while */ + + /* Should be pointing to the last component in the path name now... */ + + /* Set up the search structure */ + check_info.parent=curr_class; + check_info.name=curr_name; + + /* Find the class with this name & parent by iterating over the open classes */ + if((curr_class=H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info)) == NULL) + HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class"); + + /* Copy it */ + if((ret_value=H5P_copy_pclass(curr_class)) == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, NULL, "can't copy property class"); + +done: + /* Free the duplicated path */ + H5MM_xfree(tmp_path); + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_open_class_path() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_class_parent + PURPOSE + Internal routine to query the parent class of a generic property class + USAGE + H5P_genclass_t *H5P_get_class_parent(pclass) + H5P_genclass_t *pclass; IN: Property class to check + RETURNS + Success: Pointer to the parent class of a property class + Failure: NULL + DESCRIPTION + This routine retrieves a pointer to the parent class for a property class. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5P_genclass_t * +H5P_get_class_parent(const H5P_genclass_t *pclass) +{ + H5P_genclass_t *ret_value; /* return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_class_parent); + + assert(pclass); + + /* Get property size */ + ret_value = pclass->parent; + + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_get_class_parent() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_close_class + PURPOSE + Internal routine to close a property list class. + USAGE + herr_t H5P_close_class(class) + H5P_genclass_t *class; IN: Property list class to close + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Releases memory and de-attach a class from the property list class hierarchy. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_close_class(void *_pclass) +{ + H5P_genclass_t *pclass=(H5P_genclass_t *)_pclass; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_close_class); + + assert(pclass); + + /* Decrement the reference count & check if the object should go away */ + if(H5P_access_class(pclass,H5P_MOD_DEC_REF) < 0) + HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, FAIL, "Can't decrement ID ref count"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5P_close_class() */ + diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index a4d983a..2959ddc 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -154,11 +154,29 @@ H5_DLL H5P_genclass_t *H5P_create_class(H5P_genclass_t *par_class, 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); +H5_DLL H5P_genclass_t *H5P_copy_pclass(H5P_genclass_t *pclass); H5_DLL herr_t H5P_add_prop(H5SL_t *props, H5P_genprop_t *prop); H5_DLL herr_t H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod); +H5_DLL htri_t H5P_exist_pclass(H5P_genclass_t *pclass, const char *name); +H5_DLL herr_t H5P_get_size_plist(H5P_genplist_t *plist, const char *name, + size_t *size); +H5_DLL herr_t H5P_get_size_pclass(H5P_genclass_t *pclass, const char *name, + size_t *size); +H5_DLL H5P_genclass_t *H5P_get_class(const H5P_genplist_t *plist); +H5_DLL herr_t H5P_get_nprops_plist(const H5P_genplist_t *plist, size_t *nprops); +H5_DLL int H5P_cmp_class(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2); +H5_DLL int H5P_cmp_plist(const H5P_genplist_t *plist1, const H5P_genplist_t *plist2); +H5_DLL int H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, + void *iter_data); +H5_DLL int H5P_iterate_pclass(hid_t pclass_id, int *idx, H5P_iterate_t iter_func, + void *iter_data); +H5_DLL herr_t H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name); +H5_DLL herr_t H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, + const char *name); +H5_DLL herr_t H5P_unregister(H5P_genclass_t *pclass, const char *name); H5_DLL char *H5P_get_class_path(H5P_genclass_t *pclass); H5_DLL H5P_genclass_t *H5P_open_class_path(const char *path); -H5_DLL int H5P_tbbt_strcmp(const void *k1, const void *k2, int cmparg); +H5_DLL H5P_genclass_t *H5P_get_class_parent(const H5P_genclass_t *pclass); H5_DLL herr_t H5P_close_class(void *_pclass); /* Testing functions */ diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index fe7f8b5..f5fd438 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -68,12 +68,13 @@ H5_DLL herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, H5_DLL herr_t H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name); H5_DLL htri_t H5P_exist_plist(H5P_genplist_t *plist, const char *name); H5_DLL char *H5P_get_class_name(H5P_genclass_t *pclass); -H5_DLL herr_t H5P_get_nprops_pclass(H5P_genclass_t *pclass, size_t *nprops, hbool_t recurse); +H5_DLL herr_t H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, + hbool_t recurse); H5_DLL herr_t H5P_register(H5P_genclass_t *pclass, const char *name, size_t size, - const 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); + const 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); H5_DLL hid_t H5P_get_driver(H5P_genplist_t *plist); H5_DLL void * H5P_get_driver_info(H5P_genplist_t *plist); H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 637528d..5d0c7d3 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -169,31 +169,23 @@ H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_g; /* Generic property list routines */ H5_DLL 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); + 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); H5_DLL char *H5Pget_class_name(hid_t pclass_id); H5_DLL hid_t H5Pcreate(hid_t cls_id); +H5_DLL 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_del, H5P_prp_copy_func_t prp_copy, + H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close); #ifdef H5_WANT_H5_V1_6_COMPAT -H5_DLL herr_t H5Pregister(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_del, - H5P_prp_copy_func_t prp_copy, - H5P_prp_close_func_t prp_close); H5_DLL herr_t H5Pinsert(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_close_func_t prp_close); #else /* H5_WANT_H5_V1_6_COMPAT */ -H5_DLL herr_t H5Pregister(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_del, - H5P_prp_copy_func_t prp_copy, - H5P_prp_compare_func_t prp_cmp, - H5P_prp_close_func_t prp_close); H5_DLL herr_t H5Pinsert(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, @@ -413,6 +405,30 @@ H5_DLL ssize_t H5Pget_elink_prefix(hid_t plist_id, char *prefix, size_t size); H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd); H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/); +/* Symbols defined for compatibility with previous versions of the HDF5 API. + * + * Use of these symbols is deprecated. + */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/* Macros */ + +/* We renamed the "root" of the property list class hierarchy */ +#define H5P_NO_CLASS H5P_ROOT + + +/* Typedefs */ + + +/* Function prototypes */ +H5_DLL herr_t H5Pregister1(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_del, H5P_prp_copy_func_t prp_copy, + H5P_prp_close_func_t prp_close); + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + #ifdef __cplusplus } #endif diff --git a/src/H5vers.txt b/src/H5vers.txt index 5745521..213af52 100644 --- a/src/H5vers.txt +++ b/src/H5vers.txt @@ -59,6 +59,7 @@ FUNCTION: H5Eset_auto; ; v10, v18 FUNCTION: H5Ewalk; H5E_walk, H5E_error; v10, v18 FUNCTION: H5Gcreate; ; v10, v18 FUNCTION: H5Gopen; ; v10, v18 +FUNCTION: H5Pregister; ; v14, v18 FUNCTION: H5Rget_obj_type; ; v16, v18 FUNCTION: H5Tcommit; ; v10, v18 FUNCTION: H5Topen; ; v10, v18 diff --git a/src/H5version.h b/src/H5version.h index 311bb3b..11841d3 100644 --- a/src/H5version.h +++ b/src/H5version.h @@ -94,6 +94,10 @@ #define H5Gopen_vers 1 #endif /* !defined(H5Gopen_vers) */ +#if !defined(H5Pregister_vers) +#define H5Pregister_vers 1 +#endif /* !defined(H5Pregister_vers) */ + #if !defined(H5Rget_obj_type_vers) #define H5Rget_obj_type_vers 1 #endif /* !defined(H5Rget_obj_type_vers) */ @@ -287,6 +291,17 @@ #error "H5Gopen_vers set to invalid value" #endif /* H5Gopen_vers */ +#if !defined(H5Pregister_vers) || H5Pregister_vers == 2 +#ifndef H5Pregister_vers +#define H5Pregister_vers 2 +#endif /* H5Pregister_vers */ +#define H5Pregister H5Pregister2 +#elif H5Pregister_vers == 1 +#define H5Pregister H5Pregister1 +#else /* H5Pregister_vers */ +#error "H5Pregister_vers set to invalid value" +#endif /* H5Pregister_vers */ + #if !defined(H5Rget_obj_type_vers) || H5Rget_obj_type_vers == 2 #ifndef H5Rget_obj_type_vers #define H5Rget_obj_type_vers 2 diff --git a/src/Makefile.am b/src/Makefile.am index cbb4178..ae4950f 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -72,8 +72,9 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \ H5Osdspace.c H5Oshared.c H5Ostab.c \ H5Oshmesg.c H5Otest.c H5Ounknown.c \ - H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ - H5Pgcpl.c \ + H5P.c H5Pacpl.c H5Pdcpl.c \ + H5Pdeprec.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ + H5Pgcpl.c H5Pint.c \ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \ H5R.c H5Rdeprec.c \ H5RC.c \ diff --git a/src/Makefile.in b/src/Makefile.in index b7f83e9..e83480a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -105,8 +105,8 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo \ H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \ - H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo \ - H5Pfmpl.lo H5Pgcpl.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \ + H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo \ + H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \ H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo \ H5S.lo H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ H5Spoint.lo H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo \ @@ -428,8 +428,8 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \ H5Osdspace.c H5Oshared.c H5Ostab.c \ H5Oshmesg.c H5Otest.c H5Ounknown.c \ - H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ - H5Pgcpl.c \ + H5P.c H5Pacpl.c H5Pdcpl.c H5Pdeprec.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ + H5Pgcpl.c H5Pint.c \ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \ H5R.c H5Rdeprec.c H5RC.c \ H5RS.c \ @@ -713,11 +713,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5P.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pacpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdcpl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdeprec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdxpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfapl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfcpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfmpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pgcpl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pint.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plapl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plcpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pocpl.Plo@am__quote@ diff --git a/test/tgenprop.c b/test/tgenprop.c index aad0db8..efc2b3b 100644 --- a/test/tgenprop.c +++ b/test/tgenprop.c @@ -80,7 +80,7 @@ test_genprop_basic_class(void) MESSAGE(5, ("Testing Basic Generic Property List Class Creation Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Check class name */ @@ -111,7 +111,7 @@ test_genprop_basic_class(void) CHECK_I(ret, "H5Pclose_class"); /* Create another new generic class, derived from file creation class */ - cid1 = H5Pcreate_class(H5P_FILE_CREATE,CLASS2_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_FILE_CREATE,CLASS2_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Check class name */ @@ -168,128 +168,108 @@ test_genprop_basic_class_prop(void) MESSAGE(5, ("Testing Basic Generic Property List Class Properties Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT, CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Check the number of properties in class */ - ret = H5Pget_nprops(cid1,&nprops); + ret = H5Pget_nprops(cid1, &nprops); CHECK_I(ret, "H5Pget_nprops"); VERIFY(nprops, 0, "H5Pget_nprops"); /* Check the existance of the first property (should fail) */ - ret = H5Pexist(cid1,PROP1_NAME); + ret = H5Pexist(cid1, PROP1_NAME); VERIFY(ret, 0, "H5Pexist"); /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Try to insert the first property again (should fail) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - VERIFY(ret, FAIL, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + VERIFY(ret, FAIL, "H5Pregister2"); /* Check the existance of the first property */ - ret = H5Pexist(cid1,PROP1_NAME); + ret = H5Pexist(cid1, PROP1_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check the size of the first property */ - ret = H5Pget_size(cid1,PROP1_NAME,&size); + ret = H5Pget_size(cid1, PROP1_NAME, &size); CHECK_I(ret, "H5Pget_size"); VERIFY(size, PROP1_SIZE, "H5Pget_size"); /* Check the number of properties in class */ - ret = H5Pget_nprops(cid1,&nprops); + ret = H5Pget_nprops(cid1, &nprops); CHECK_I(ret, "H5Pget_nprops"); VERIFY(nprops, 1, "H5Pget_nprops"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Try to insert the second property again (should fail) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - VERIFY(ret, FAIL, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + VERIFY(ret, FAIL, "H5Pregister2"); /* Check the existance of the second property */ - ret = H5Pexist(cid1,PROP2_NAME); + ret = H5Pexist(cid1, PROP2_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check the size of the second property */ - ret = H5Pget_size(cid1,PROP2_NAME,&size); + ret = H5Pget_size(cid1, PROP2_NAME, &size); CHECK_I(ret, "H5Pget_size"); VERIFY(size, PROP2_SIZE, "H5Pget_size"); /* Check the number of properties in class */ - ret = H5Pget_nprops(cid1,&nprops); + ret = H5Pget_nprops(cid1, &nprops); CHECK_I(ret, "H5Pget_nprops"); VERIFY(nprops, 2, "H5Pget_nprops"); /* Insert third property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Check the existance of the third property */ - ret = H5Pexist(cid1,PROP3_NAME); + ret = H5Pexist(cid1, PROP3_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check the size of the third property */ - ret = H5Pget_size(cid1,PROP3_NAME,&size); + ret = H5Pget_size(cid1, PROP3_NAME, &size); CHECK_I(ret, "H5Pget_size"); VERIFY(size, PROP3_SIZE, "H5Pget_size"); /* Check the number of properties in class */ - ret = H5Pget_nprops(cid1,&nprops); + ret = H5Pget_nprops(cid1, &nprops); CHECK_I(ret, "H5Pget_nprops"); VERIFY(nprops, 3, "H5Pget_nprops"); /* Unregister first property */ - ret = H5Punregister(cid1,PROP1_NAME); + ret = H5Punregister(cid1, PROP1_NAME); CHECK_I(ret, "H5Punregister"); /* Try to check the size of the first property (should fail) */ - ret = H5Pget_size(cid1,PROP1_NAME,&size); + ret = H5Pget_size(cid1, PROP1_NAME, &size); VERIFY(ret, FAIL, "H5Pget_size"); /* Check the number of properties in class */ - ret = H5Pget_nprops(cid1,&nprops); + ret = H5Pget_nprops(cid1, &nprops); CHECK_I(ret, "H5Pget_nprops"); VERIFY(nprops, 2, "H5Pget_nprops"); /* Unregister second property */ - ret = H5Punregister(cid1,PROP2_NAME); + ret = H5Punregister(cid1, PROP2_NAME); CHECK_I(ret, "H5Punregister"); /* Check the number of properties in class */ - ret = H5Pget_nprops(cid1,&nprops); + ret = H5Pget_nprops(cid1, &nprops); CHECK_I(ret, "H5Pget_nprops"); VERIFY(nprops, 1, "H5Pget_nprops"); /* Unregister third property */ - ret = H5Punregister(cid1,PROP3_NAME); + ret = H5Punregister(cid1, PROP3_NAME); CHECK_I(ret, "H5Punregister"); /* Check the number of properties in class */ - ret = H5Pget_nprops(cid1,&nprops); + ret = H5Pget_nprops(cid1, &nprops); CHECK_I(ret, "H5Pget_nprops"); VERIFY(nprops, 0, "H5Pget_nprops"); @@ -344,40 +324,24 @@ test_genprop_class_iter(void) MESSAGE(5, ("Testing Basic Generic Property List Class Property Iteration Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT, CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert third property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert third property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Check the number of properties in class */ ret = H5Pget_nprops(cid1,&nprops); @@ -456,40 +420,24 @@ test_genprop_class_callback(void) MESSAGE(5, ("Testing Basic Generic Property List Class Callback Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,test_genprop_cls_cb1,&crt_cb_struct,NULL,NULL,test_genprop_cls_cb1,&cls_cb_struct); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,test_genprop_cls_cb1,&crt_cb_struct,NULL, NULL,test_genprop_cls_cb1,&cls_cb_struct); CHECK_I(cid1, "H5Pcreate_class"); /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert third property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert fourth property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Check the number of properties in class */ ret = H5Pget_nprops(cid1,&nprops); @@ -571,26 +519,18 @@ test_genprop_basic_list(void) MESSAGE(5, ("Testing Basic Generic Property List Creation Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Add several properties (w/default values) */ /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Check the number of properties in class */ ret = H5Pget_nprops(cid1,&nprops); @@ -627,24 +567,24 @@ test_genprop_basic_list(void) VERIFY(nprops, 2, "H5Pget_nprops"); /* Check existence of properties */ - ret = H5Pexist(lid1,PROP1_NAME); + ret = H5Pexist(lid1, PROP1_NAME); VERIFY(ret, 1, "H5Pexist"); - ret = H5Pexist(lid1,PROP2_NAME); + ret = H5Pexist(lid1, PROP2_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check the sizes of the properties */ - ret = H5Pget_size(lid1,PROP1_NAME,&size); + ret = H5Pget_size(lid1, PROP1_NAME,&size); CHECK_I(ret, "H5Pget_size"); VERIFY(size, PROP1_SIZE, "H5Pget_size"); - ret = H5Pget_size(lid1,PROP2_NAME,&size); + ret = H5Pget_size(lid1, PROP2_NAME,&size); CHECK_I(ret, "H5Pget_size"); VERIFY(size, PROP2_SIZE, "H5Pget_size"); /* Check values of properties (set with default values) */ - ret = H5Pget(lid1,PROP1_NAME,&prop1_value); + ret = H5Pget(lid1, PROP1_NAME,&prop1_value); CHECK_I(ret, "H5Pget"); VERIFY(prop1_value, *PROP1_DEF_VALUE, "H5Pget"); - ret = H5Pget(lid1,PROP2_NAME,&prop2_value); + ret = H5Pget(lid1, PROP2_NAME,&prop2_value); CHECK_I(ret, "H5Pget"); /* Verify the floating-poing value in this way to avoid compiler warning. */ if(!FLT_ABS_EQUAL(prop2_value,*PROP2_DEF_VALUE)) @@ -685,26 +625,18 @@ test_genprop_basic_list_prop(void) MESSAGE(5, ("Testing Basic Generic Property List Property Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Add several properties (several w/default values) */ /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Create a property list from the class */ lid1 = H5Pcreate(cid1); @@ -719,17 +651,17 @@ test_genprop_basic_list_prop(void) /* Insert first temporary property into class (with no callbacks) */ #ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pinsert(lid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL); #else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pinsert(lid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); #endif /* H5_WANT_H5_V1_6_COMPAT */ CHECK_I(ret, "H5Pinsert"); /* Insert second temporary property into class (with no callbacks) */ #ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pinsert(lid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL); #else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pinsert(lid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); #endif /* H5_WANT_H5_V1_6_COMPAT */ CHECK_I(ret, "H5Pinsert"); @@ -739,20 +671,20 @@ test_genprop_basic_list_prop(void) VERIFY(nprops, 4, "H5Pget_nprops"); /* Check existence of all properties */ - ret = H5Pexist(lid1,PROP1_NAME); + ret = H5Pexist(lid1, PROP1_NAME); VERIFY(ret, 1, "H5Pexist"); - ret = H5Pexist(lid1,PROP2_NAME); + ret = H5Pexist(lid1, PROP2_NAME); VERIFY(ret, 1, "H5Pexist"); - ret = H5Pexist(lid1,PROP3_NAME); + ret = H5Pexist(lid1, PROP3_NAME); VERIFY(ret, 1, "H5Pexist"); - ret = H5Pexist(lid1,PROP4_NAME); + ret = H5Pexist(lid1, PROP4_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check values of permanent properties (set with default values) */ - ret = H5Pget(lid1,PROP1_NAME,&prop1_value); + ret = H5Pget(lid1, PROP1_NAME,&prop1_value); CHECK_I(ret, "H5Pget"); VERIFY(prop1_value, *PROP1_DEF_VALUE, "H5Pget"); - ret = H5Pget(lid1,PROP2_NAME,&prop2_value); + ret = H5Pget(lid1, PROP2_NAME,&prop2_value); CHECK_I(ret, "H5Pget"); /* Verify the floating-poing value in this way to avoid compiler warning. */ if(!FLT_ABS_EQUAL(prop2_value,*PROP2_DEF_VALUE)) @@ -761,11 +693,11 @@ test_genprop_basic_list_prop(void) /* Check values of temporary properties (set with regular values) */ - ret = H5Pget(lid1,PROP3_NAME,&prop3_value); + ret = H5Pget(lid1, PROP3_NAME,&prop3_value); CHECK_I(ret, "H5Pget"); - if(HDmemcmp(&prop3_value,PROP3_DEF_VALUE,PROP3_SIZE)!=0) + if(HDmemcmp(&prop3_value, PROP3_DEF_VALUE, PROP3_SIZE)!=0) TestErrPrintf("Property #3 doesn't match!, line=%d\n",__LINE__); - ret = H5Pget(lid1,PROP4_NAME,&prop4_value); + ret = H5Pget(lid1, PROP4_NAME,&prop4_value); CHECK_I(ret, "H5Pget"); /* Verify the floating-poing value in this way to avoid compiler warning. */ if(!FLT_ABS_EQUAL(prop4_value,*PROP4_DEF_VALUE)) @@ -773,7 +705,7 @@ test_genprop_basic_list_prop(void) "H5Pget", *PROP4_DEF_VALUE, prop4_value, (int)__LINE__, __FILE__); /* Delete permanent property */ - ret = H5Premove(lid1,PROP2_NAME); + ret = H5Premove(lid1, PROP2_NAME); CHECK_I(ret, "H5Premove"); /* Check number of properties */ @@ -782,7 +714,7 @@ test_genprop_basic_list_prop(void) VERIFY(nprops, 3, "H5Pget_nprops"); /* Delete temporary property */ - ret = H5Premove(lid1,PROP3_NAME); + ret = H5Premove(lid1, PROP3_NAME); CHECK_I(ret, "H5Premove"); /* Check number of properties */ @@ -791,18 +723,18 @@ test_genprop_basic_list_prop(void) VERIFY(nprops, 2, "H5Pget_nprops"); /* Check existence of remaining properties */ - ret = H5Pexist(lid1,PROP1_NAME); + ret = H5Pexist(lid1, PROP1_NAME); VERIFY(ret, 1, "H5Pexist"); - ret = H5Pexist(lid1,PROP4_NAME); + ret = H5Pexist(lid1, PROP4_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check values of permanent properties (set with default values) */ - ret = H5Pget(lid1,PROP1_NAME,&prop1_value); + ret = H5Pget(lid1, PROP1_NAME,&prop1_value); CHECK_I(ret, "H5Pget"); VERIFY(prop1_value, *PROP1_DEF_VALUE, "H5Pget"); /* Check values of temporary properties (set with regular values) */ - ret = H5Pget(lid1,PROP4_NAME,&prop4_value); + ret = H5Pget(lid1, PROP4_NAME,&prop4_value); CHECK_I(ret, "H5Pget"); /* Verify the floating-poing value in this way to avoid compiler warning. */ if(!FLT_ABS_EQUAL(prop4_value,*PROP4_DEF_VALUE)) @@ -867,26 +799,18 @@ test_genprop_list_iter(void) MESSAGE(5, ("Testing Generic Property List Iteration Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Add several properties (several w/default values) */ /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Create a property list from the class */ lid1 = H5Pcreate(cid1); @@ -901,17 +825,17 @@ test_genprop_list_iter(void) /* Insert first temporary property into class (with no callbacks) */ #ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pinsert(lid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL); #else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pinsert(lid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); #endif /* H5_WANT_H5_V1_6_COMPAT */ CHECK_I(ret, "H5Pinsert"); /* Insert second temporary property into class (with no callbacks) */ #ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pinsert(lid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL); #else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pinsert(lid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); + ret = H5Pinsert(lid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); #endif /* H5_WANT_H5_V1_6_COMPAT */ CHECK_I(ret, "H5Pinsert"); @@ -1141,40 +1065,24 @@ test_genprop_list_callback(void) MESSAGE(5, ("Testing Basic Generic Property List Property Callback Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,test_genprop_cls_cb2,&cop_cb_struct,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL,test_genprop_cls_cb2,&cop_cb_struct,NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Insert first property into class (with callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,test_genprop_prop_crt_cb1,test_genprop_prop_set_cb1,test_genprop_prop_get_cb1,NULL,test_genprop_prop_cop_cb1,test_genprop_prop_cls_cb1); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,test_genprop_prop_crt_cb1,test_genprop_prop_set_cb1,test_genprop_prop_get_cb1,NULL,test_genprop_prop_cop_cb1,test_genprop_prop_cmp_cb1,test_genprop_prop_cls_cb1); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE,test_genprop_prop_crt_cb1,test_genprop_prop_set_cb1,test_genprop_prop_get_cb1,NULL,test_genprop_prop_cop_cb1,test_genprop_prop_cmp_cb1,test_genprop_prop_cls_cb1); + CHECK_I(ret, "H5Pregister2"); /* Insert second property into class (with only delete callback) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,test_genprop_prop_del_cb2,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,test_genprop_prop_del_cb2,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL,test_genprop_prop_del_cb2,NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert third property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP3_NAME,PROP3_SIZE,PROP3_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert fourth property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP4_NAME,PROP4_SIZE,PROP4_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP4_NAME, PROP4_SIZE, PROP4_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Check the number of properties in class */ ret = H5Pget_nprops(cid1,&nprops); @@ -1195,16 +1103,16 @@ test_genprop_list_callback(void) /* Verify creation callback information for properties tracked */ VERIFY(prop1_cb_info.crt_count, 1, "H5Pcreate"); - if(HDstrcmp(prop1_cb_info.crt_name,PROP1_NAME)!=0) + if(HDstrcmp(prop1_cb_info.crt_name, PROP1_NAME)!=0) TestErrPrintf("Property #1 name doesn't match!, line=%d\n",__LINE__); - if(HDmemcmp(prop1_cb_info.crt_value,PROP1_DEF_VALUE,PROP1_SIZE)!=0) + if(HDmemcmp(prop1_cb_info.crt_value, PROP1_DEF_VALUE, PROP1_SIZE)!=0) TestErrPrintf("Property #1 value doesn't match!, line=%d\n",__LINE__); /* Check values of permanent properties (set with default values) */ - ret = H5Pget(lid1,PROP1_NAME,&prop1_value); + ret = H5Pget(lid1, PROP1_NAME,&prop1_value); CHECK_I(ret, "H5Pget"); VERIFY(prop1_value, *PROP1_DEF_VALUE, "H5Pget"); - ret = H5Pget(lid1,PROP2_NAME,&prop2_value); + ret = H5Pget(lid1, PROP2_NAME,&prop2_value); CHECK_I(ret, "H5Pget"); /* Verify the floating-poing value in this way to avoid compiler warning. */ if(!FLT_ABS_EQUAL(prop2_value,*PROP2_DEF_VALUE)) @@ -1212,11 +1120,11 @@ test_genprop_list_callback(void) "H5Pget", *PROP2_DEF_VALUE, prop2_value, (int)__LINE__, __FILE__); /* Check values of temporary properties (set with regular values) */ - ret = H5Pget(lid1,PROP3_NAME,&prop3_value); + ret = H5Pget(lid1, PROP3_NAME,&prop3_value); CHECK_I(ret, "H5Pget"); - if(HDmemcmp(&prop3_value,PROP3_DEF_VALUE,PROP3_SIZE)!=0) + if(HDmemcmp(&prop3_value, PROP3_DEF_VALUE, PROP3_SIZE)!=0) TestErrPrintf("Property #3 doesn't match!, line=%d\n",__LINE__); - ret = H5Pget(lid1,PROP4_NAME,&prop4_value); + ret = H5Pget(lid1, PROP4_NAME,&prop4_value); CHECK_I(ret, "H5Pget"); /* Verify the floating-poing value in this way to avoid compiler warning. */ if(!FLT_ABS_EQUAL(prop4_value,*PROP4_DEF_VALUE)) @@ -1226,46 +1134,46 @@ test_genprop_list_callback(void) /* Verify get callback information for properties tracked */ VERIFY(prop1_cb_info.get_count, 1, "H5Pget"); VERIFY(prop1_cb_info.get_plist_id, lid1, "H5Pget"); - if(HDstrcmp(prop1_cb_info.get_name,PROP1_NAME)!=0) + if(HDstrcmp(prop1_cb_info.get_name, PROP1_NAME)!=0) TestErrPrintf("Property #1 name doesn't match!, line=%d\n",__LINE__); - if(HDmemcmp(prop1_cb_info.get_value,PROP1_DEF_VALUE,PROP1_SIZE)!=0) + if(HDmemcmp(prop1_cb_info.get_value, PROP1_DEF_VALUE, PROP1_SIZE)!=0) TestErrPrintf("Property #1 value doesn't match!, line=%d\n",__LINE__); /* Set value of property #1 to different value */ - ret = H5Pset(lid1,PROP1_NAME,&prop1_new_value); + ret = H5Pset(lid1, PROP1_NAME,&prop1_new_value); CHECK_I(ret, "H5Pset"); /* Verify set callback information for properties tracked */ VERIFY(prop1_cb_info.set_count, 1, "H5Pset"); VERIFY(prop1_cb_info.set_plist_id, lid1, "H5Pset"); - if(HDstrcmp(prop1_cb_info.set_name,PROP1_NAME)!=0) + if(HDstrcmp(prop1_cb_info.set_name, PROP1_NAME)!=0) TestErrPrintf("Property #1 name doesn't match!, line=%d\n",__LINE__); - if(HDmemcmp(prop1_cb_info.set_value,&prop1_new_value,PROP1_SIZE)!=0) + if(HDmemcmp(prop1_cb_info.set_value,&prop1_new_value, PROP1_SIZE)!=0) TestErrPrintf("Property #1 value doesn't match!, line=%d\n",__LINE__); /* Check new value of tracked properties */ - ret = H5Pget(lid1,PROP1_NAME,&prop1_value); + ret = H5Pget(lid1, PROP1_NAME,&prop1_value); CHECK_I(ret, "H5Pget"); VERIFY(prop1_value, prop1_new_value, "H5Pget"); /* Verify get callback information again for properties tracked */ VERIFY(prop1_cb_info.get_count, 2, "H5Pget"); VERIFY(prop1_cb_info.get_plist_id, lid1, "H5Pget"); - if(HDstrcmp(prop1_cb_info.get_name,PROP1_NAME)!=0) + if(HDstrcmp(prop1_cb_info.get_name, PROP1_NAME)!=0) TestErrPrintf("Property #1 name doesn't match!, line=%d\n",__LINE__); - if(HDmemcmp(prop1_cb_info.get_value,&prop1_new_value,PROP1_SIZE)!=0) + if(HDmemcmp(prop1_cb_info.get_value,&prop1_new_value, PROP1_SIZE)!=0) TestErrPrintf("Property #1 value doesn't match!, line=%d\n",__LINE__); /* Delete property #2 */ - ret = H5Premove(lid1,PROP2_NAME); + ret = H5Premove(lid1, PROP2_NAME); CHECK_I(ret, "H5Premove"); /* Verify delete callback information for properties tracked */ VERIFY(prop2_cb_info.del_count, 1, "H5Premove"); VERIFY(prop2_cb_info.del_plist_id, lid1, "H5Premove"); - if(HDstrcmp(prop2_cb_info.del_name,PROP2_NAME)!=0) + if(HDstrcmp(prop2_cb_info.del_name, PROP2_NAME)!=0) TestErrPrintf("Property #2 name doesn't match!, line=%d\n",__LINE__); - if(HDmemcmp(prop2_cb_info.del_value,PROP2_DEF_VALUE,PROP2_SIZE)!=0) + if(HDmemcmp(prop2_cb_info.del_value, PROP2_DEF_VALUE, PROP2_SIZE)!=0) TestErrPrintf("Property #2 value doesn't match!, line=%d\n",__LINE__); /* Copy first list */ @@ -1274,9 +1182,9 @@ test_genprop_list_callback(void) /* Verify copy callback information for properties tracked */ VERIFY(prop1_cb_info.cop_count, 1, "H5Pcopy"); - if(HDstrcmp(prop1_cb_info.cop_name,PROP1_NAME)!=0) + if(HDstrcmp(prop1_cb_info.cop_name, PROP1_NAME)!=0) TestErrPrintf("Property #1 name doesn't match!, line=%d\n",__LINE__); - if(HDmemcmp(prop1_cb_info.cop_value,&prop1_new_value,PROP1_SIZE)!=0) + if(HDmemcmp(prop1_cb_info.cop_value,&prop1_new_value, PROP1_SIZE)!=0) TestErrPrintf("Property #1 value doesn't match!, line=%d\n",__LINE__); /* Verify that the class creation callback occurred */ @@ -1298,9 +1206,9 @@ test_genprop_list_callback(void) /* Verify close callback information for properties tracked */ VERIFY(prop1_cb_info.cls_count, 1, "H5Pclose"); - if(HDstrcmp(prop1_cb_info.cls_name,PROP1_NAME)!=0) + if(HDstrcmp(prop1_cb_info.cls_name, PROP1_NAME)!=0) TestErrPrintf("Property #1 name doesn't match!, line=%d\n",__LINE__); - if(HDmemcmp(prop1_cb_info.cls_value,&prop1_new_value,PROP1_SIZE)!=0) + if(HDmemcmp(prop1_cb_info.cls_value,&prop1_new_value, PROP1_SIZE)!=0) TestErrPrintf("Property #1 value doesn't match!, line=%d\n",__LINE__); /* Close second list */ @@ -1367,11 +1275,11 @@ test_genprop_list_addprop(void) CHECK_I(ret, "H5Pinsert"); /* Check existence of added property */ - ret = H5Pexist(pid,PROP1_NAME); + ret = H5Pexist(pid, PROP1_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check values of property (set with default value) */ - ret = H5Pget(pid,PROP1_NAME,&prop1_value); + ret = H5Pget(pid, PROP1_NAME,&prop1_value); CHECK_I(ret, "H5Pget"); VERIFY(prop1_value, *PROP1_DEF_VALUE, "H5Pget"); @@ -1434,7 +1342,7 @@ test_genprop_class_addprop(void) CHECK(sid, FAIL, "H5Screate"); /* Create a new class, dervied from the dataset creation property list class */ - cid = H5Pcreate_class(H5P_DATASET_CREATE,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid = H5Pcreate_class(H5P_DATASET_CREATE,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid, "H5Pcreate_class"); /* Check existence of an original property */ @@ -1442,12 +1350,8 @@ test_genprop_class_addprop(void) VERIFY(ret, 0, "H5Pexist"); /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Create a derived dataset creation property list */ pid = H5Pcreate(cid); @@ -1519,24 +1423,16 @@ test_genprop_equal(void) MESSAGE(5, ("Testing Basic Generic Property List Equal Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Create a property list from the class */ lid1 = H5Pcreate(cid1); @@ -1575,16 +1471,12 @@ test_genprop_path(void) MESSAGE(5, ("Testing Generic Property List Class Path Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Get full path for first class */ path=H5P_get_class_path_test(cid1); @@ -1594,16 +1486,12 @@ test_genprop_path(void) HDfree(path); /* Create another new generic class, derived from first class */ - cid2 = H5Pcreate_class(cid1,CLASS2_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid2 = H5Pcreate_class(cid1,CLASS2_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid2, "H5Pcreate_class"); /* Insert second property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid2,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid2,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid2, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Get full path for second class */ path=H5P_get_class_path_test(cid2); @@ -1654,16 +1542,12 @@ test_genprop_refcount(void) MESSAGE(5, ("Testing Generic Property List Reference Count Functionality\n")); /* Create a new generic class, derived from the root of the class hierarchy */ - cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME,NULL,NULL,NULL,NULL,NULL,NULL); + cid1 = H5Pcreate_class(H5P_ROOT,CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); CHECK_I(cid1, "H5Pcreate_class"); /* Insert first property into class (with no callbacks) */ -#ifdef H5_WANT_H5_V1_6_COMPAT - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); -#else /* H5_WANT_H5_V1_6_COMPAT */ - ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* H5_WANT_H5_V1_6_COMPAT */ - CHECK_I(ret, "H5Pregister"); + ret = H5Pregister2(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister2"); /* Create a new generic list, derived from the root of the class hierarchy */ lid1 = H5Pcreate(cid1); @@ -1712,6 +1596,136 @@ test_genprop_refcount(void) } /* ent test_genprop_refcount() */ +#ifndef H5_NO_DEPRECATED_SYMBOLS +/**************************************************************** +** +** test_genprop_deprec(): Test basic generic property list code. +** Tests deprecated API routines. +** +****************************************************************/ +static void +test_genprop_deprec(void) +{ + hid_t cid1; /* Generic Property class ID */ + size_t size; /* Size of property */ + size_t nprops; /* Number of properties in class */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Deprecated Generic Property List Functions\n")); + + /* Create a new generic class, derived from the root of the class hierarchy */ + cid1 = H5Pcreate_class(H5P_ROOT, CLASS1_NAME, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(cid1, "H5Pcreate_class"); + + /* Check the number of properties in class */ + ret = H5Pget_nprops(cid1, &nprops); + CHECK_I(ret, "H5Pget_nprops"); + VERIFY(nprops, 0, "H5Pget_nprops"); + + /* Check the existance of the first property (should fail) */ + ret = H5Pexist(cid1, PROP1_NAME); + VERIFY(ret, 0, "H5Pexist"); + + /* Insert first property into class (with no callbacks) */ + ret = H5Pregister1(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister1"); + + /* Try to insert the first property again (should fail) */ + ret = H5Pregister1(cid1, PROP1_NAME, PROP1_SIZE, PROP1_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); + VERIFY(ret, FAIL, "H5Pregister1"); + + /* Check the existance of the first property */ + ret = H5Pexist(cid1, PROP1_NAME); + VERIFY(ret, 1, "H5Pexist"); + + /* Check the size of the first property */ + ret = H5Pget_size(cid1, PROP1_NAME, &size); + CHECK_I(ret, "H5Pget_size"); + VERIFY(size, PROP1_SIZE, "H5Pget_size"); + + /* Check the number of properties in class */ + ret = H5Pget_nprops(cid1, &nprops); + CHECK_I(ret, "H5Pget_nprops"); + VERIFY(nprops, 1, "H5Pget_nprops"); + + /* Insert second property into class (with no callbacks) */ + ret = H5Pregister1(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister1"); + + /* Try to insert the second property again (should fail) */ + ret = H5Pregister1(cid1, PROP2_NAME, PROP2_SIZE, PROP2_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); + VERIFY(ret, FAIL, "H5Pregister1"); + + /* Check the existance of the second property */ + ret = H5Pexist(cid1, PROP2_NAME); + VERIFY(ret, 1, "H5Pexist"); + + /* Check the size of the second property */ + ret = H5Pget_size(cid1, PROP2_NAME, &size); + CHECK_I(ret, "H5Pget_size"); + VERIFY(size, PROP2_SIZE, "H5Pget_size"); + + /* Check the number of properties in class */ + ret = H5Pget_nprops(cid1, &nprops); + CHECK_I(ret, "H5Pget_nprops"); + VERIFY(nprops, 2, "H5Pget_nprops"); + + /* Insert third property into class (with no callbacks) */ + ret = H5Pregister1(cid1, PROP3_NAME, PROP3_SIZE, PROP3_DEF_VALUE, NULL, NULL, NULL, NULL, NULL, NULL); + CHECK_I(ret, "H5Pregister1"); + + /* Check the existance of the third property */ + ret = H5Pexist(cid1, PROP3_NAME); + VERIFY(ret, 1, "H5Pexist"); + + /* Check the size of the third property */ + ret = H5Pget_size(cid1, PROP3_NAME, &size); + CHECK_I(ret, "H5Pget_size"); + VERIFY(size, PROP3_SIZE, "H5Pget_size"); + + /* Check the number of properties in class */ + ret = H5Pget_nprops(cid1, &nprops); + CHECK_I(ret, "H5Pget_nprops"); + VERIFY(nprops, 3, "H5Pget_nprops"); + + /* Unregister first property */ + ret = H5Punregister(cid1, PROP1_NAME); + CHECK_I(ret, "H5Punregister"); + + /* Try to check the size of the first property (should fail) */ + ret = H5Pget_size(cid1, PROP1_NAME, &size); + VERIFY(ret, FAIL, "H5Pget_size"); + + /* Check the number of properties in class */ + ret = H5Pget_nprops(cid1, &nprops); + CHECK_I(ret, "H5Pget_nprops"); + VERIFY(nprops, 2, "H5Pget_nprops"); + + /* Unregister second property */ + ret = H5Punregister(cid1, PROP2_NAME); + CHECK_I(ret, "H5Punregister"); + + /* Check the number of properties in class */ + ret = H5Pget_nprops(cid1, &nprops); + CHECK_I(ret, "H5Pget_nprops"); + VERIFY(nprops, 1, "H5Pget_nprops"); + + /* Unregister third property */ + ret = H5Punregister(cid1, PROP3_NAME); + CHECK_I(ret, "H5Punregister"); + + /* Check the number of properties in class */ + ret = H5Pget_nprops(cid1, &nprops); + CHECK_I(ret, "H5Pget_nprops"); + VERIFY(nprops, 0, "H5Pget_nprops"); + + /* Close class */ + ret = H5Pclose_class(cid1); + CHECK_I(ret, "H5Pclose_class"); +} /* end test_genprop_deprec() */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + /**************************************************************** ** ** test_genprop(): Main generic property testing routine. @@ -1741,6 +1755,10 @@ test_genprop(void) test_genprop_path(); /* Tests for class path verification */ test_genprop_refcount(); /* Tests for class reference counting */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + test_genprop_deprec(); /* Tests for deprecated routines */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + } /* test_genprop() */ -- cgit v0.12