mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-12 15:04:59 +08:00
[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)
This commit is contained in:
parent
7e5d420349
commit
ec65ddbef6
187
src/H5P.c
187
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() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,14 +1463,28 @@ 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");
|
||||
|
Loading…
Reference in New Issue
Block a user