summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-10-08 17:16:07 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-10-08 17:16:07 (GMT)
commitec65ddbef69ca67f0b40f06e45694d8ea076692e (patch)
treebf3b2698e85a1073ea5d9a7ce4a561220c040e6d
parent7e5d420349ddab3b5e8b8e35293433d5b452a977 (diff)
downloadhdf5-ec65ddbef69ca67f0b40f06e45694d8ea076692e.zip
hdf5-ec65ddbef69ca67f0b40f06e45694d8ea076692e.tar.gz
hdf5-ec65ddbef69ca67f0b40f06e45694d8ea076692e.tar.bz2
[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)
-rw-r--r--src/H5P.c187
-rw-r--r--src/H5Pprivate.h6
-rw-r--r--src/H5Ppublic.h3
-rw-r--r--test/tgenprop.c28
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");