From ec65ddbef69ca67f0b40f06e45694d8ea076692e Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 8 Oct 2002 12:16:07 -0500 Subject: [svn-r5964] Purpose: Internal feature. Description: To complement the "get the class's path" functionality, there needs to be a way to open a generic property class with a path. Solution: Implement the "open a class by path" functionality. Also, add internal testing routines. Platforms tested: FreeBSD 4.6 (sleipnir) (too small for triple testing) --- src/H5P.c | 187 +++++++++++++++++++++++++++++++++++++++++++++---------- src/H5Pprivate.h | 6 +- src/H5Ppublic.h | 3 - test/tgenprop.c | 28 ++++++--- 4 files changed, 180 insertions(+), 44 deletions(-) diff --git a/src/H5P.c b/src/H5P.c index 964d627..0fec1c2 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -13,6 +13,7 @@ /* $Id$ */ #define H5P_PACKAGE /*suppress error about including H5Ppkg */ +#define H5P_TESTING /*suppress warning about H5P testing funcs*/ /* Private header files */ #include "H5private.h" /* Generic Functions */ @@ -355,14 +356,14 @@ H5P_term_interface(void) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static hid_t +static H5P_genclass_t * H5P_copy_pclass(H5P_genclass_t *pclass) { H5P_genclass_t *new_pclass = NULL; /* Property list class copied */ H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */ H5P_genprop_t *pcopy; /* Copy of property to insert into class */ - unsigned u; /* Local index variable */ - hid_t ret_value=FAIL; /* return value */ + unsigned u; /* Local index variable */ + H5P_genclass_t *ret_value=NULL; /* return value */ FUNC_ENTER_NOINIT(H5P_copy_pclass); @@ -374,7 +375,7 @@ H5P_copy_pclass(H5P_genclass_t *pclass) /* Create the new property list class */ if (NULL==(new_pclass=H5P_create_class(pclass->parent, pclass->name, pclass->hashsize, 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, FAIL, "unable to create property list class"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list class"); /* Copy the properties registered for this class */ if(pclass->nprops>0) { @@ -386,11 +387,11 @@ H5P_copy_pclass(H5P_genclass_t *pclass) while(tmp!=NULL) { /* Make a copy of the class's property */ if((pcopy=H5P_dup_prop(tmp))==NULL) - HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property"); + 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,new_pclass->hashsize,pcopy)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into class"); + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class"); /* Increment property count for class */ new_pclass->nprops++; @@ -404,14 +405,13 @@ H5P_copy_pclass(H5P_genclass_t *pclass) /* Increment parent class's derived class value */ if(new_pclass->parent!=NULL) if(H5P_access_class(new_pclass->parent,H5P_MOD_INC_CLS)<0) - HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't increment parent class ref count"); + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment parent class ref count"); - /* Get an atom for the class */ - if ((ret_value = H5I_register(H5I_GENPROP_CLS, new_pclass))<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); + /* Set the return value */ + ret_value=new_pclass; done: - if (ret_value<0 && new_pclass) + if (ret_value==NULL && new_pclass) H5P_close_class(new_pclass); FUNC_LEAVE (ret_value); @@ -573,8 +573,17 @@ hid_t H5Pcopy(hid_t id) } /* end if */ /* Must be property classes */ else { - if((ret_value=H5P_copy_pclass(obj))<0) + H5P_genclass_t *copy_class; /* Copy of class */ + + /* Copy the class */ + 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) { + H5P_close_class(copy_class); + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); + } /* end if */ } /* end else */ done: @@ -1063,7 +1072,7 @@ H5P_check_class(void *_obj, hid_t id, const void *_key) assert(key); /* Check if the class object has the same parent as the new class */ - if(obj->parent!=NULL && obj->parent==key->parent) { + 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 */ @@ -1127,19 +1136,6 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned hashsize, assert(hashsize>0); } - /* Check that the class name is unique in the parent class */ - if(par_class!=NULL) { - H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */ - - /* Set up the search structure */ - check_info.parent=par_class; - check_info.name=name; - - /* Iterate over the open class IDs and fail if any have the same parent and name */ - if(H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info)!=NULL) - HGOTO_ERROR (H5E_PLIST, H5E_DUPCLASS, NULL, "duplicated class name in parent class"); - } /* end if */ - /* Allocate room for the class & it's hash table of properties */ if (NULL==(pclass = H5MM_calloc (sizeof(H5P_genclass_t)+((hashsize-1)*sizeof(H5P_genprop_t *))))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); @@ -4702,14 +4698,15 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -char *H5P_get_class_path(H5P_genclass_t *pclass) +static 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(H5P_get_class_path, NULL); + FUNC_ENTER_NOINIT(H5P_get_class_path); assert(pclass); @@ -4726,7 +4723,7 @@ char *H5P_get_class_path(H5P_genclass_t *pclass) * 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, FAIL, "memory allocation failed for class name"); + 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); @@ -4769,12 +4766,13 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -char *H5Pget_class_path_test(hid_t pclass_id) +char * +H5P_get_class_path_test(hid_t pclass_id) { H5P_genclass_t *pclass; /* Property class to query */ char *ret_value; /* return value */ - FUNC_ENTER_API(H5Pget_class_path_test, NULL); + FUNC_ENTER_NOAPI(H5P_get_class_path_test, NULL); /* Check arguments. */ if (NULL == (pclass = H5I_object_verify(pclass_id, H5I_GENPROP_CLS))) @@ -4786,7 +4784,132 @@ char *H5Pget_class_path_test(hid_t pclass_id) done: FUNC_LEAVE (ret_value); -} /* H5Pget_class_path_test() */ +} /* H5P_get_class_path_test() */ + + +/*-------------------------------------------------------------------------- + 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 +--------------------------------------------------------------------------*/ +static 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_NOINIT(H5P_open_class_path); + + assert(path); + + /* Duplicate the path to use */ + tmp_path=HDstrdup(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 (ret_value); +} /* H5P_open_class_path() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Popen_class_path + PURPOSE + Routine to open a [copy of] a class with its full path name + USAGE + hid_t H5Popen_class_name(path) + const char *path; IN: Full path name of class to open [copy of] + RETURNS + Success: ID of generic property class + Failure: NULL + DESCRIPTION + This routine opens [a copy] of the class indicated by the full path. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING H5P_open_class_path() + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hid_t H5P_open_class_path_test(const char *path) +{ + H5P_genclass_t *pclass=NULL;/* Property class to query */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_open_class_path_test, FAIL); + + /* Check arguments. */ + if (NULL == path || *path=='\0') + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid class path"); + + /* Open the property list class */ + if ((pclass=H5P_open_class_path(path))==NULL) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "unable to find class with full path"); + + /* 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 (ret_value); +} /* H5P_open_class_path_test() */ /*-------------------------------------------------------------------------- diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index b0de67a..2f962c2 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -40,7 +40,6 @@ 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 char *H5P_get_class_path(H5P_genclass_t *pclass); H5_DLL herr_t H5P_get_nprops_pclass(H5P_genclass_t *pclass, size_t *nprops); H5_DLL herr_t H5P_register(H5P_genclass_t *pclass, const char *name, size_t size, void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, @@ -64,6 +63,11 @@ H5_DLL herr_t H5P_fill_value_defined(H5P_genplist_t *plist, H5_DLL htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id); H5_DLL void *H5P_object_verify(hid_t plist_id, hid_t pclass_id); +/* Testing functions */ +#ifdef H5P_TESTING +H5_DLL char *H5P_get_class_path_test(hid_t pclass_id); +H5_DLL hid_t H5P_open_class_path_test(const char *path); +#endif /* H5P_TESTING */ /* Private functions to "peek" at properties of a certain type */ H5_DLL unsigned H5P_peek_unsigned(H5P_genplist_t *plist, const char *name); diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index d2ab774..07cbec2 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -115,9 +115,6 @@ H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name, unsigned hashsize, 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); -#ifdef H5P_TESTING -H5_DLL char *H5Pget_class_path_test(hid_t pclass_id); -#endif /* H5P_TESTING */ H5_DLL hid_t H5Pcreate(hid_t cls_id); 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, diff --git a/test/tgenprop.c b/test/tgenprop.c index a12b1e9..bddbec9 100644 --- a/test/tgenprop.c +++ b/test/tgenprop.c @@ -26,6 +26,7 @@ #include "testhdf5.h" #include "hdf5.h" #include "H5Dprivate.h" /* For Dataset creation property list names */ +#include "H5Pprivate.h" /* For H5P testing functions */ #define FILENAME "tgenprop.h5" @@ -524,10 +525,6 @@ test_genprop_basic_list(void) cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL); CHECK_I(cid1, "H5Pcreate_class"); - /* Create a the generic class again, should fail */ - cid2 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL); - VERIFY(cid2, FAIL, "H5Pcreate_class"); - /* Add several properties (w/default values) */ /* Insert first property into class (with no callbacks) */ @@ -1433,6 +1430,7 @@ test_genprop_path(void) { hid_t cid1; /* Generic Property class ID */ hid_t cid2; /* Generic Property class ID */ + hid_t cid3; /* Generic Property class ID */ char *path; /* Class path */ herr_t ret; /* Generic return value */ @@ -1448,8 +1446,8 @@ test_genprop_path(void) CHECK_I(ret, "H5Pregister"); /* Get full path for first class */ - path=H5Pget_class_path_test(cid1); - CHECK_PTR(path, "H5Pget_class_path_test"); + path=H5P_get_class_path_test(cid1); + CHECK_PTR(path, "H5P_get_class_path_test"); if(HDstrcmp(path,CLASS1_PATH)!=0) { num_errs++; printf("Class names don't match!, path=%s, CLASS1_PATH=%s\n",path,CLASS1_PATH); @@ -1465,15 +1463,29 @@ test_genprop_path(void) CHECK_I(ret, "H5Pregister"); /* Get full path for second class */ - path=H5Pget_class_path_test(cid2); - CHECK_PTR(path, "H5Pget_class_path_test"); + path=H5P_get_class_path_test(cid2); + CHECK_PTR(path, "H5P_get_class_path_test"); if(HDstrcmp(path,CLASS2_PATH)!=0) { num_errs++; printf("Class names don't match!, path=%s, CLASS2_PATH=%s\n",path,CLASS2_PATH); } /* end if */ + + /* Open a copy of the class with the path name */ + cid3 = H5P_open_class_path_test(path); + CHECK_I(cid3, "H5Popen_class_path"); + + /* Check that the classes are equal */ + ret = H5Pequal(cid2,cid3); + VERIFY(ret, 1, "H5Pequal"); + + /* Release the path string */ free(path); /* Close class */ + ret = H5Pclose_class(cid3); + CHECK_I(ret, "H5Pclose_class"); + + /* Close class */ ret = H5Pclose_class(cid1); CHECK_I(ret, "H5Pclose_class"); -- cgit v0.12