diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2004-01-08 14:55:19 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2004-01-08 14:55:19 (GMT) |
commit | 300af1d8097dc15ad2a30b7813b66eeb54118b48 (patch) | |
tree | 2a4ad717c79e92c2f31d5c427f522041a67354b6 | |
parent | 4264e3444aaba267c5ad6848437e5d89d043ba70 (diff) | |
download | hdf5-300af1d8097dc15ad2a30b7813b66eeb54118b48.zip hdf5-300af1d8097dc15ad2a30b7813b66eeb54118b48.tar.gz hdf5-300af1d8097dc15ad2a30b7813b66eeb54118b48.tar.bz2 |
[svn-r8039] Purpose:
Bug fix
Description:
When two property lists are compared, the H5Pequal routine was just
comparing the raw information for the property values. This causes problems
when the raw information contains pointers to other information.
Solution:
Allow a 'compare' callback to be registered for properties, so that a user
application get perform the comparison itself, allowing for "deep" compares of
the property value.
This was exported to the H5Pregister & H5Pinsert routines in the development
branch, but not the release branch.
Platforms tested:
FreeBSD 4.9 (sleipnir)
h5committest
-rw-r--r-- | src/H5AC.c | 12 | ||||
-rw-r--r-- | src/H5D.c | 275 | ||||
-rw-r--r-- | src/H5Dprivate.h | 3 | ||||
-rw-r--r-- | src/H5F.c | 50 | ||||
-rw-r--r-- | src/H5FDmpio.c | 4 | ||||
-rw-r--r-- | src/H5P.c | 196 | ||||
-rw-r--r-- | src/H5Ppkg.h | 1 | ||||
-rw-r--r-- | src/H5Pprivate.h | 5 | ||||
-rw-r--r-- | src/H5Ppublic.h | 2 | ||||
-rw-r--r-- | test/dsets.c | 88 |
10 files changed, 526 insertions, 110 deletions
@@ -217,11 +217,11 @@ H5AC_init_interface(void) /* Insert 'block before metadata write' property */ block_before_meta_write=1; - if(H5P_insert(xfer_plist,H5AC_BLOCK_BEFORE_META_WRITE_NAME,H5AC_BLOCK_BEFORE_META_WRITE_SIZE,&block_before_meta_write,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(xfer_plist,H5AC_BLOCK_BEFORE_META_WRITE_NAME,H5AC_BLOCK_BEFORE_META_WRITE_SIZE,&block_before_meta_write,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property"); /* Insert 'library internal' property */ - if(H5P_insert(xfer_plist,H5AC_LIBRARY_INTERNAL_NAME,H5AC_LIBRARY_INTERNAL_SIZE,&library_internal,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(xfer_plist,H5AC_LIBRARY_INTERNAL_NAME,H5AC_LIBRARY_INTERNAL_SIZE,&library_internal,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property"); /* Set the transfer mode */ @@ -241,11 +241,11 @@ H5AC_init_interface(void) /* Insert 'block before metadata write' property */ block_before_meta_write=0; - if(H5P_insert(xfer_plist,H5AC_BLOCK_BEFORE_META_WRITE_NAME,H5AC_BLOCK_BEFORE_META_WRITE_SIZE,&block_before_meta_write,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(xfer_plist,H5AC_BLOCK_BEFORE_META_WRITE_NAME,H5AC_BLOCK_BEFORE_META_WRITE_SIZE,&block_before_meta_write,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property"); /* Insert 'library internal' property */ - if(H5P_insert(xfer_plist,H5AC_LIBRARY_INTERNAL_NAME,H5AC_LIBRARY_INTERNAL_SIZE,&library_internal,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(xfer_plist,H5AC_LIBRARY_INTERNAL_NAME,H5AC_LIBRARY_INTERNAL_SIZE,&library_internal,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property"); /* Set the transfer mode */ @@ -265,11 +265,11 @@ H5AC_init_interface(void) /* Insert 'block before metadata write' property */ block_before_meta_write=0; - if(H5P_insert(xfer_plist,H5AC_BLOCK_BEFORE_META_WRITE_NAME,H5AC_BLOCK_BEFORE_META_WRITE_SIZE,&block_before_meta_write,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(xfer_plist,H5AC_BLOCK_BEFORE_META_WRITE_NAME,H5AC_BLOCK_BEFORE_META_WRITE_SIZE,&block_before_meta_write,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property"); /* Insert 'library internal' property */ - if(H5P_insert(xfer_plist,H5AC_LIBRARY_INTERNAL_NAME,H5AC_LIBRARY_INTERNAL_SIZE,&library_internal,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(xfer_plist,H5AC_LIBRARY_INTERNAL_NAME,H5AC_LIBRARY_INTERNAL_SIZE,&library_internal,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert metadata cache dxpl property"); /* Set the transfer mode */ @@ -48,6 +48,9 @@ static int interface_initialize_g = 0; /* Local functions */ static herr_t H5D_init_interface(void); static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite, hid_t dxpl_id); +static int H5D_crt_fill_value_cmp(const void *value1, const void *value2, size_t size); +static int H5D_crt_ext_file_list_cmp(const void *value1, const void *value2, size_t size); +static int H5D_crt_data_pipeline_cmp(const void *value1, const void *value2, size_t size); static H5D_t * H5D_new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type); static H5D_t * H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t dxpl_id); @@ -215,73 +218,73 @@ H5D_init_interface(void) /* Assume that if there are properties in the class, they are the default ones */ if(nprops==0) { /* Register the max. temp buffer size property */ - if(H5P_register(xfer_pclass,H5D_XFER_MAX_TEMP_BUF_NAME,H5D_XFER_MAX_TEMP_BUF_SIZE,&def_max_temp_buf,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_MAX_TEMP_BUF_NAME,H5D_XFER_MAX_TEMP_BUF_SIZE,&def_max_temp_buf,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the type conversion buffer property */ - if(H5P_register(xfer_pclass,H5D_XFER_TCONV_BUF_NAME,H5D_XFER_TCONV_BUF_SIZE,&def_tconv_buf,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_TCONV_BUF_NAME,H5D_XFER_TCONV_BUF_SIZE,&def_tconv_buf,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the background buffer property */ - if(H5P_register(xfer_pclass,H5D_XFER_BKGR_BUF_NAME,H5D_XFER_BKGR_BUF_SIZE,&def_bkgr_buf,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_BKGR_BUF_NAME,H5D_XFER_BKGR_BUF_SIZE,&def_bkgr_buf,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the background buffer type property */ - if(H5P_register(xfer_pclass,H5D_XFER_BKGR_BUF_TYPE_NAME,H5D_XFER_BKGR_BUF_TYPE_SIZE,&def_bkgr_buf_type,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_BKGR_BUF_TYPE_NAME,H5D_XFER_BKGR_BUF_TYPE_SIZE,&def_bkgr_buf_type,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the B-Tree node splitting ratios property */ - if(H5P_register(xfer_pclass,H5D_XFER_BTREE_SPLIT_RATIO_NAME,H5D_XFER_BTREE_SPLIT_RATIO_SIZE,&def_btree_split_ratio,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_BTREE_SPLIT_RATIO_NAME,H5D_XFER_BTREE_SPLIT_RATIO_SIZE,&def_btree_split_ratio,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); #ifdef H5_WANT_H5_V1_4_COMPAT /* Register the hyperslab caching property */ - if(H5P_register(xfer_pclass,H5D_XFER_HYPER_CACHE_NAME,H5D_XFER_HYPER_CACHE_SIZE,&def_hyper_cache,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_HYPER_CACHE_NAME,H5D_XFER_HYPER_CACHE_SIZE,&def_hyper_cache,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the hyperslab cache limit property */ - if(H5P_register(xfer_pclass,H5D_XFER_HYPER_CACHE_LIM_NAME,H5D_XFER_HYPER_CACHE_LIM_SIZE,&def_hyper_cache_lim,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_HYPER_CACHE_LIM_NAME,H5D_XFER_HYPER_CACHE_LIM_SIZE,&def_hyper_cache_lim,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); #endif /* H5_WANT_H5_V1_4_COMPAT */ /* Register the vlen allocation function property */ - if(H5P_register(xfer_pclass,H5D_XFER_VLEN_ALLOC_NAME,H5D_XFER_VLEN_ALLOC_SIZE,&def_vlen_alloc,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_VLEN_ALLOC_NAME,H5D_XFER_VLEN_ALLOC_SIZE,&def_vlen_alloc,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the vlen allocation information property */ - if(H5P_register(xfer_pclass,H5D_XFER_VLEN_ALLOC_INFO_NAME,H5D_XFER_VLEN_ALLOC_INFO_SIZE,&def_vlen_alloc_info,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_VLEN_ALLOC_INFO_NAME,H5D_XFER_VLEN_ALLOC_INFO_SIZE,&def_vlen_alloc_info,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the vlen free function property */ - if(H5P_register(xfer_pclass,H5D_XFER_VLEN_FREE_NAME,H5D_XFER_VLEN_FREE_SIZE,&def_vlen_free,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_VLEN_FREE_NAME,H5D_XFER_VLEN_FREE_SIZE,&def_vlen_free,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the vlen free information property */ - if(H5P_register(xfer_pclass,H5D_XFER_VLEN_FREE_INFO_NAME,H5D_XFER_VLEN_FREE_INFO_SIZE,&def_vlen_free_info,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_VLEN_FREE_INFO_NAME,H5D_XFER_VLEN_FREE_INFO_SIZE,&def_vlen_free_info,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the file driver ID property */ - if(H5P_register(xfer_pclass,H5D_XFER_VFL_ID_NAME,H5D_XFER_VFL_ID_SIZE,&def_vfl_id,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_VFL_ID_NAME,H5D_XFER_VFL_ID_SIZE,&def_vfl_id,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the file driver info property */ - if(H5P_register(xfer_pclass,H5D_XFER_VFL_INFO_NAME,H5D_XFER_VFL_INFO_SIZE,&def_vfl_info,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_VFL_INFO_NAME,H5D_XFER_VFL_INFO_SIZE,&def_vfl_info,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the vector size property */ - if(H5P_register(xfer_pclass,H5D_XFER_HYPER_VECTOR_SIZE_NAME,H5D_XFER_HYPER_VECTOR_SIZE_SIZE,&def_hyp_vec_size,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_HYPER_VECTOR_SIZE_NAME,H5D_XFER_HYPER_VECTOR_SIZE_SIZE,&def_hyp_vec_size,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the I/O transfer mode property */ - if(H5P_register(xfer_pclass,H5D_XFER_IO_XFER_MODE_NAME,H5D_XFER_IO_XFER_MODE_SIZE,&def_io_xfer_mode,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_IO_XFER_MODE_NAME,H5D_XFER_IO_XFER_MODE_SIZE,&def_io_xfer_mode,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the EDC property */ - if(H5P_register(xfer_pclass,H5D_XFER_EDC_NAME,H5D_XFER_EDC_SIZE,&enable_edc,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_EDC_NAME,H5D_XFER_EDC_SIZE,&enable_edc,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the filter callback property */ - if(H5P_register(xfer_pclass,H5D_XFER_FILTER_CB_NAME,H5D_XFER_FILTER_CB_SIZE,&filter_cb,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(xfer_pclass,H5D_XFER_FILTER_CB_NAME,H5D_XFER_FILTER_CB_SIZE,&filter_cb,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); } /* end if */ @@ -307,35 +310,35 @@ H5D_init_interface(void) /* Assume that if there are properties in the class, they are the default ones */ if(nprops==0) { /* Register the storage layout property */ - if(H5P_register(crt_pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &layout, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &layout, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the chunking dimensionality property */ - if(H5P_register(crt_pclass, H5D_CRT_CHUNK_DIM_NAME, H5D_CRT_CHUNK_DIM_SIZE, &chunk_ndims, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_CHUNK_DIM_NAME, H5D_CRT_CHUNK_DIM_SIZE, &chunk_ndims, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the chunking size property */ - if(H5P_register(crt_pclass, H5D_CRT_CHUNK_SIZE_NAME, H5D_CRT_CHUNK_SIZE_SIZE, chunk_size, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_CHUNK_SIZE_NAME, H5D_CRT_CHUNK_SIZE_SIZE, chunk_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the fill value property */ - if(H5P_register(crt_pclass, H5D_CRT_FILL_VALUE_NAME, H5D_CRT_FILL_VALUE_SIZE, &fill, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_FILL_VALUE_NAME, H5D_CRT_FILL_VALUE_SIZE, &fill, NULL, NULL, NULL, NULL, NULL, H5D_CRT_FILL_VALUE_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the space allocation time property */ - if(H5P_register(crt_pclass, H5D_CRT_ALLOC_TIME_NAME, H5D_CRT_ALLOC_TIME_SIZE, &alloc_time, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_ALLOC_TIME_NAME, H5D_CRT_ALLOC_TIME_SIZE, &alloc_time, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the fill value writing time property */ - if(H5P_register(crt_pclass, H5D_CRT_FILL_TIME_NAME, H5D_CRT_FILL_TIME_SIZE, &fill_time, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_FILL_TIME_NAME, H5D_CRT_FILL_TIME_SIZE, &fill_time, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the external file list property */ - if(H5P_register(crt_pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &efl, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &efl, NULL, NULL, NULL, NULL, NULL, H5D_CRT_EXT_FILE_LIST_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the data pipeline property */ - if(H5P_register(crt_pclass, H5D_CRT_DATA_PIPELINE_NAME, H5D_CRT_DATA_PIPELINE_SIZE, &pline, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + if(H5P_register(crt_pclass, H5D_CRT_DATA_PIPELINE_NAME, H5D_CRT_DATA_PIPELINE_SIZE, &pline, NULL, NULL, NULL, NULL, NULL, H5D_CRT_DATA_PIPELINE_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); } /* end if */ @@ -568,6 +571,228 @@ done: /*------------------------------------------------------------------------- + * Function: H5D_crt_fill_value_cmp + * + * Purpose: Callback routine which is called whenever the fill value + * property in the dataset creation property list is compared. + * + * Return: positive if VALUE1 is greater than VALUE2, negative if + * VALUE2 is greater than VALUE1 and zero if VALUE1 and + * VALUE2 are equal. + * + * Programmer: Quincey Koziol + * Wednesday, January 7, 2004 + * + * Modification: + * + *------------------------------------------------------------------------- + */ +static int +H5D_crt_fill_value_cmp(const void *value1, const void *value2, size_t size) +{ + const H5O_fill_t *fill1=(const H5O_fill_t *)value1, /* Create local aliases for values */ + *fill2=(const H5O_fill_t *)value2; + int cmp_value; /* Value from comparison */ + herr_t ret_value=0; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_crt_fill_value_cmp) + + /* Sanity check */ + assert(fill1); + assert(fill2); + assert(size==sizeof(H5O_fill_t)); + + /* Check the size of fill values */ + if(fill1->size < fill2->size) HGOTO_DONE(-1); + if(fill1->size > fill2->size) HGOTO_DONE(1); + + /* Check the types of the fill values */ + if(fill1->type==NULL && fill2->type!=NULL) HGOTO_DONE(-1); + if(fill1->type!=NULL && fill2->type==NULL) HGOTO_DONE(1); + if(fill1->type!=NULL) + if((cmp_value=H5T_cmp(fill1->type,fill2->type))!=0) + HGOTO_DONE(cmp_value); + + /* Check the fill values in the buffers */ + if(fill1->buf==NULL && fill2->buf!=NULL) HGOTO_DONE(-1); + if(fill1->buf!=NULL && fill2->buf==NULL) HGOTO_DONE(1); + if(fill1->buf!=NULL) + if((cmp_value=HDmemcmp(fill1->buf,fill2->buf,fill1->size))!=0) + HGOTO_DONE(cmp_value); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_crt_fill_value_cmp() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_crt_ext_file_list_cmp + * + * Purpose: Callback routine which is called whenever the external file + * list property in the dataset creation property list is + * compared. + * + * Return: positive if VALUE1 is greater than VALUE2, negative if + * VALUE2 is greater than VALUE1 and zero if VALUE1 and + * VALUE2 are equal. + * + * Programmer: Quincey Koziol + * Wednesday, January 7, 2004 + * + * Modification: + * + *------------------------------------------------------------------------- + */ +static int +H5D_crt_ext_file_list_cmp(const void *value1, const void *value2, size_t size) +{ + const H5O_efl_t *efl1=(const H5O_efl_t *)value1, /* Create local aliases for values */ + *efl2=(const H5O_efl_t *)value2; + int cmp_value; /* Value from comparison */ + herr_t ret_value=0; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_crt_ext_file_list_cmp) + + /* Sanity check */ + assert(efl1); + assert(efl2); + assert(size==sizeof(H5O_efl_t)); + + /* Check the heap address of external file lists */ + if((cmp_value=H5F_addr_cmp(efl1->heap_addr,efl2->heap_addr))!=0) + HGOTO_DONE(cmp_value); + + /* Check the number of allocated efl entries */ + if(efl1->nalloc < efl2->nalloc) HGOTO_DONE(-1); + if(efl1->nalloc > efl2->nalloc) HGOTO_DONE(1); + + /* Check the number of used efl entries */ + if(efl1->nused < efl2->nused) HGOTO_DONE(-1); + if(efl1->nused > efl2->nused) HGOTO_DONE(1); + + /* Check the efl entry information */ + if(efl1->slot==NULL && efl2->slot!=NULL) HGOTO_DONE(-1); + if(efl1->slot!=NULL && efl2->slot==NULL) HGOTO_DONE(1); + if(efl1->slot!=NULL && efl1->nused>0) { + int i; /* Local index variable */ + + /* Loop through all entries, comparing them */ + for(i=0; i<efl1->nused; i++) { + /* Check the name offset of the efl entry */ + if(efl1->slot[i].name_offset < efl2->slot[i].name_offset) HGOTO_DONE(-1); + if(efl1->slot[i].name_offset > efl2->slot[i].name_offset) HGOTO_DONE(1); + + /* Check the name of the efl entry */ + if(efl1->slot[i].name==NULL && efl2->slot[i].name!=NULL) HGOTO_DONE(-1); + if(efl1->slot[i].name!=NULL && efl2->slot[i].name==NULL) HGOTO_DONE(1); + if(efl1->slot[i].name!=NULL) + if((cmp_value=HDstrcmp(efl1->slot[i].name,efl2->slot[i].name))!=0) + HGOTO_DONE(cmp_value); + + /* Check the file offset of the efl entry */ + if(efl1->slot[i].offset < efl2->slot[i].offset) HGOTO_DONE(-1); + if(efl1->slot[i].offset > efl2->slot[i].offset) HGOTO_DONE(1); + + /* Check the file size of the efl entry */ + if(efl1->slot[i].size < efl2->slot[i].size) HGOTO_DONE(-1); + if(efl1->slot[i].size > efl2->slot[i].size) HGOTO_DONE(1); + } /* end for */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_crt_ext_file_list_cmp() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_crt_data_pipeline_cmp + * + * Purpose: Callback routine which is called whenever the filter pipeline + * property in the dataset creation property list is compared. + * + * Return: positive if VALUE1 is greater than VALUE2, negative if + * VALUE2 is greater than VALUE1 and zero if VALUE1 and + * VALUE2 are equal. + * + * Programmer: Quincey Koziol + * Wednesday, January 7, 2004 + * + * Modification: + * + *------------------------------------------------------------------------- + */ +static int +H5D_crt_data_pipeline_cmp(const void *value1, const void *value2, size_t size) +{ + const H5O_pline_t *pline1=(const H5O_pline_t *)value1, /* Create local aliases for values */ + *pline2=(const H5O_pline_t *)value2; + int cmp_value; /* Value from comparison */ + herr_t ret_value=0; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_crt_data_pipeline_cmp) + + /* Sanity check */ + assert(pline1); + assert(pline2); + assert(size==sizeof(H5O_pline_t)); + + /* Check the number of allocated pipeline entries */ + if(pline1->nalloc < pline2->nalloc) HGOTO_DONE(-1); + if(pline1->nalloc > pline2->nalloc) HGOTO_DONE(1); + + /* Check the number of used pipeline entries */ + if(pline1->nfilters < pline2->nfilters) HGOTO_DONE(-1); + if(pline1->nfilters > pline2->nfilters) HGOTO_DONE(1); + + /* Check the filter entry information */ + if(pline1->filter==NULL && pline2->filter!=NULL) HGOTO_DONE(-1); + if(pline1->filter!=NULL && pline2->filter==NULL) HGOTO_DONE(1); + if(pline1->filter!=NULL && pline1->nfilters>0) { + int i; /* Local index variable */ + + /* Loop through all filters, comparing them */ + for(i=0; i<pline1->nfilters; i++) { + /* Check the ID of the filter */ + if(pline1->filter[i].id < pline2->filter[i].id) HGOTO_DONE(-1); + if(pline1->filter[i].id > pline2->filter[i].id) HGOTO_DONE(1); + + /* Check the flags for the filter */ + if(pline1->filter[i].flags < pline2->filter[i].flags) HGOTO_DONE(-1); + if(pline1->filter[i].flags > pline2->filter[i].flags) HGOTO_DONE(1); + + /* Check the name of the filter */ + if(pline1->filter[i].name==NULL && pline2->filter[i].name!=NULL) HGOTO_DONE(-1); + if(pline1->filter[i].name!=NULL && pline2->filter[i].name==NULL) HGOTO_DONE(1); + if(pline1->filter[i].name!=NULL) + if((cmp_value=HDstrcmp(pline1->filter[i].name,pline2->filter[i].name))!=0) + HGOTO_DONE(cmp_value); + + /* Check the number of parameters for the filter */ + if(pline1->filter[i].cd_nelmts < pline2->filter[i].cd_nelmts) HGOTO_DONE(-1); + if(pline1->filter[i].cd_nelmts > pline2->filter[i].cd_nelmts) HGOTO_DONE(1); + + /* Check the filter parameter information */ + if(pline1->filter[i].cd_values==NULL && pline2->filter[i].cd_values!=NULL) HGOTO_DONE(-1); + if(pline1->filter[i].cd_values!=NULL && pline2->filter[i].cd_values==NULL) HGOTO_DONE(1); + if(pline1->filter[i].cd_values!=NULL && pline1->filter[i].cd_nelmts>0) { + size_t v; /* Local index variable */ + + /* Loop through all parameters, comparing them */ + for(v=0; v<pline1->filter[i].cd_nelmts; v++) { + /* Check each parameter for the filter */ + if(pline1->filter[i].cd_values[v] < pline2->filter[i].cd_values[v]) HGOTO_DONE(-1); + if(pline1->filter[i].cd_values[v] > pline2->filter[i].cd_values[v]) HGOTO_DONE(1); + } /* end for */ + } /* end if */ + } /* end for */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_crt_data_pipeline_cmp() */ + + +/*------------------------------------------------------------------------- * Function: H5D_xfer_create * * Purpose: Callback routine which is called whenever any dataset transfer diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index b1615b0..c63a0b7 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -52,6 +52,7 @@ #define H5D_CRT_FILL_VALUE_NAME "fill_value" #define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t) #define H5D_CRT_FILL_VALUE_DEF {NULL, 0, NULL} +#define H5D_CRT_FILL_VALUE_CMP H5D_crt_fill_value_cmp /* Definitions for space allocation time */ #define H5D_CRT_ALLOC_TIME_NAME "alloc_time" #define H5D_CRT_ALLOC_TIME_SIZE sizeof(H5D_alloc_time_t) @@ -64,10 +65,12 @@ #define H5D_CRT_EXT_FILE_LIST_NAME "efl" #define H5D_CRT_EXT_FILE_LIST_SIZE sizeof(H5O_efl_t) #define H5D_CRT_EXT_FILE_LIST_DEF {HADDR_UNDEF, 0, 0, NULL} +#define H5D_CRT_EXT_FILE_LIST_CMP H5D_crt_ext_file_list_cmp /* Definitions for data filter pipeline */ #define H5D_CRT_DATA_PIPELINE_NAME "pline" #define H5D_CRT_DATA_PIPELINE_SIZE sizeof(H5O_pline_t) #define H5D_CRT_DATA_PIPELINE_DEF {0, 0, NULL} +#define H5D_CRT_DATA_PIPELINE_CMP H5D_crt_data_pipeline_cmp /* ======== Data transfer properties ======== */ /* Definitions for maximum temp buffer size property */ @@ -270,39 +270,39 @@ H5F_init_interface(void) /* Assume that if there are properties in the class, they are the default ones */ if(nprops==0) { /* Register the user block size */ - if(H5P_register(crt_pclass,H5F_CRT_USER_BLOCK_NAME,H5F_CRT_USER_BLOCK_SIZE, &userblock_size,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_USER_BLOCK_NAME,H5F_CRT_USER_BLOCK_SIZE, &userblock_size,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the 1/2 rank for symbol table leaf nodes */ - if(H5P_register(crt_pclass,H5F_CRT_SYM_LEAF_NAME,H5F_CRT_SYM_LEAF_SIZE, &sym_leaf_k,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_SYM_LEAF_NAME,H5F_CRT_SYM_LEAF_SIZE, &sym_leaf_k,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the 1/2 rank for btree internal nodes */ - if(H5P_register(crt_pclass,H5F_CRT_BTREE_RANK_NAME,H5F_CRT_BTREE_RANK_SIZE, btree_k,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_BTREE_RANK_NAME,H5F_CRT_BTREE_RANK_SIZE, btree_k,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the byte number for an address */ - if(H5P_register(crt_pclass,H5F_CRT_ADDR_BYTE_NUM_NAME, H5F_CRT_ADDR_BYTE_NUM_SIZE, &sizeof_addr,NULL,NULL,NULL,NULL,NULL, NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_ADDR_BYTE_NUM_NAME, H5F_CRT_ADDR_BYTE_NUM_SIZE, &sizeof_addr,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the byte number for object size */ - if(H5P_register(crt_pclass,H5F_CRT_OBJ_BYTE_NUM_NAME, H5F_CRT_OBJ_BYTE_NUM_SIZE,&sizeof_size,NULL,NULL,NULL,NULL,NULL, NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_OBJ_BYTE_NUM_NAME, H5F_CRT_OBJ_BYTE_NUM_SIZE,&sizeof_size,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the superblock version number */ - if(H5P_register(crt_pclass,H5F_CRT_SUPER_VERS_NAME,H5F_CRT_SUPER_VERS_SIZE, &superblock_ver,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_SUPER_VERS_NAME,H5F_CRT_SUPER_VERS_SIZE, &superblock_ver,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the free-space version number */ - if(H5P_register(crt_pclass,H5F_CRT_FREESPACE_VERS_NAME, H5F_CRT_FREESPACE_VERS_SIZE,&freespace_ver,NULL,NULL,NULL,NULL,NULL, NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_FREESPACE_VERS_NAME, H5F_CRT_FREESPACE_VERS_SIZE,&freespace_ver,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the object directory version number */ - if(H5P_register(crt_pclass,H5F_CRT_OBJ_DIR_VERS_NAME, H5F_CRT_OBJ_DIR_VERS_SIZE,&objectdir_ver,NULL,NULL,NULL,NULL,NULL, NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_OBJ_DIR_VERS_NAME, H5F_CRT_OBJ_DIR_VERS_SIZE,&objectdir_ver,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the shared-header version number */ - if(H5P_register(crt_pclass,H5F_CRT_SHARE_HEAD_VERS_NAME, H5F_CRT_SHARE_HEAD_VERS_SIZE, &sharedheader_ver,NULL,NULL,NULL,NULL, NULL,NULL)<0) + if(H5P_register(crt_pclass,H5F_CRT_SHARE_HEAD_VERS_NAME, H5F_CRT_SHARE_HEAD_VERS_SIZE, &sharedheader_ver,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); } /* end if */ @@ -356,63 +356,63 @@ H5F_init_interface(void) /* Assume that if there are properties in the class, they are the default ones */ if(nprops==0) { /* Register the size of meta data cache(elements) */ - if(H5P_register(acs_pclass,H5F_ACS_META_CACHE_SIZE_NAME,H5F_ACS_META_CACHE_SIZE_SIZE, &mdc_nelmts,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_META_CACHE_SIZE_NAME,H5F_ACS_META_CACHE_SIZE_SIZE, &mdc_nelmts,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the size of raw data chunk cache (elements) */ - if(H5P_register(acs_pclass,H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME,H5F_ACS_DATA_CACHE_ELMT_SIZE_SIZE, &rdcc_nelmts,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME,H5F_ACS_DATA_CACHE_ELMT_SIZE_SIZE, &rdcc_nelmts,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the size of raw data chunk cache(bytes) */ - if(H5P_register(acs_pclass,H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME,H5F_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME,H5F_ACS_DATA_CACHE_BYTE_SIZE_SIZE, &rdcc_nbytes,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the preemption for reading chunks */ - if(H5P_register(acs_pclass,H5F_ACS_PREEMPT_READ_CHUNKS_NAME,H5F_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_PREEMPT_READ_CHUNKS_NAME,H5F_ACS_PREEMPT_READ_CHUNKS_SIZE, &rdcc_w0,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the threshold for alignment */ - if(H5P_register(acs_pclass,H5F_ACS_ALIGN_THRHD_NAME,H5F_ACS_ALIGN_THRHD_SIZE, &threshold,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_ALIGN_THRHD_NAME,H5F_ACS_ALIGN_THRHD_SIZE, &threshold,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the alignment */ - if(H5P_register(acs_pclass,H5F_ACS_ALIGN_NAME,H5F_ACS_ALIGN_SIZE, &alignment,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_ALIGN_NAME,H5F_ACS_ALIGN_SIZE, &alignment,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the minimum metadata allocation block size */ - if(H5P_register(acs_pclass,H5F_ACS_META_BLOCK_SIZE_NAME,H5F_ACS_META_BLOCK_SIZE_SIZE, &meta_block_size,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_META_BLOCK_SIZE_NAME,H5F_ACS_META_BLOCK_SIZE_SIZE, &meta_block_size,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the maximum sieve buffer size */ - if(H5P_register(acs_pclass,H5F_ACS_SIEVE_BUF_SIZE_NAME,H5F_ACS_SIEVE_BUF_SIZE_SIZE, &sieve_buf_size,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_SIEVE_BUF_SIZE_NAME,H5F_ACS_SIEVE_BUF_SIZE_SIZE, &sieve_buf_size,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the minimum "small data" allocation block size */ - if(H5P_register(acs_pclass,H5F_ACS_SDATA_BLOCK_SIZE_NAME,H5F_ACS_SDATA_BLOCK_SIZE_SIZE, &sdata_block_size,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_SDATA_BLOCK_SIZE_NAME,H5F_ACS_SDATA_BLOCK_SIZE_SIZE, &sdata_block_size,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the garbage collection reference */ - if(H5P_register(acs_pclass,H5F_ACS_GARBG_COLCT_REF_NAME,H5F_ACS_GARBG_COLCT_REF_SIZE, &gc_ref,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_GARBG_COLCT_REF_NAME,H5F_ACS_GARBG_COLCT_REF_SIZE, &gc_ref,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the file driver ID */ - if(H5P_register(acs_pclass,H5F_ACS_FILE_DRV_ID_NAME,H5F_ACS_FILE_DRV_ID_SIZE, &driver_id,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_FILE_DRV_ID_NAME,H5F_ACS_FILE_DRV_ID_SIZE, &driver_id,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the file driver info */ - if(H5P_register(acs_pclass,H5F_ACS_FILE_DRV_INFO_NAME,H5F_ACS_FILE_DRV_INFO_SIZE, &driver_info,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_FILE_DRV_INFO_NAME,H5F_ACS_FILE_DRV_INFO_SIZE, &driver_info,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the file close degree */ - if(H5P_register(acs_pclass,H5F_CLOSE_DEGREE_NAME,H5F_CLOSE_DEGREE_SIZE, &close_degree,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_CLOSE_DEGREE_NAME,H5F_CLOSE_DEGREE_SIZE, &close_degree,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the offset of family driver info */ - if(H5P_register(acs_pclass,H5F_ACS_FAMILY_OFFSET_NAME,H5F_ACS_FAMILY_OFFSET_SIZE, &family_offset,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_FAMILY_OFFSET_NAME,H5F_ACS_FAMILY_OFFSET_SIZE, &family_offset,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); /* Register the data type of multi driver info */ - if(H5P_register(acs_pclass,H5F_ACS_MULTI_TYPE_NAME,H5F_ACS_MULTI_TYPE_SIZE, &mem_type,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(acs_pclass,H5F_ACS_MULTI_TYPE_NAME,H5F_ACS_MULTI_TYPE_SIZE, &mem_type,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); } /* end if */ @@ -437,7 +437,7 @@ H5F_init_interface(void) /* Assume that if there are properties in the class, they are the default ones */ if(nprops==0) { /* Register property of whether symlinks is local to file */ - if(H5P_register(mnt_pclass,H5F_MNT_SYM_LOCAL_NAME,H5F_MNT_SYM_LOCAL_SIZE, &local,NULL,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_register(mnt_pclass,H5F_MNT_SYM_LOCAL_NAME,H5F_MNT_SYM_LOCAL_SIZE, &local,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); } /* end if */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index a1fbe7c..f791ddb 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -640,11 +640,11 @@ H5FD_mpio_setup(hid_t dxpl_id, MPI_Datatype btype, MPI_Datatype ftype) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dataset transfer list"); /* Set buffer MPI type */ - if(H5P_insert(plist,H5FD_MPIO_XFER_MEM_MPI_TYPE_NAME,H5FD_MPIO_XFER_MEM_MPI_TYPE_SIZE,&btype,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(plist,H5FD_MPIO_XFER_MEM_MPI_TYPE_NAME,H5FD_MPIO_XFER_MEM_MPI_TYPE_SIZE,&btype,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert MPI-I/O property"); /* Set file MPI type */ - if(H5P_insert(plist,H5FD_MPIO_XFER_FILE_MPI_TYPE_NAME,H5FD_MPIO_XFER_FILE_MPI_TYPE_SIZE,&ftype,NULL,NULL,NULL,NULL,NULL)<0) + if(H5P_insert(plist,H5FD_MPIO_XFER_FILE_MPI_TYPE_NAME,H5FD_MPIO_XFER_FILE_MPI_TYPE_SIZE,&ftype,NULL,NULL,NULL,NULL,NULL,NULL)<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't insert MPI-I/O property"); done: @@ -823,6 +823,7 @@ done: 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 @@ -840,7 +841,8 @@ H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type, 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_close_func_t prp_close) + 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 */ @@ -876,6 +878,11 @@ H5P_create_prop(const char *name, size_t size, H5P_prop_within_t type, 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 */ @@ -1756,6 +1763,7 @@ done: 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 @@ -1778,11 +1786,12 @@ done: 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, - void **initial_value); + 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. - void **initial_value; IN/OUT: The initial value for the property being created. + 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 @@ -1792,10 +1801,11 @@ done: 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, - void **value); + 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 @@ -1805,10 +1815,11 @@ done: 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, - void *value); + 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 @@ -1818,10 +1829,11 @@ done: 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, - void *value); + 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 @@ -1830,20 +1842,38 @@ done: 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, void *value); + 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 closed. - void *value; IN: The value of the property being closed. + 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, void *value); + 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 @@ -1873,7 +1903,8 @@ 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, 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_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 */ @@ -1928,7 +1959,7 @@ H5P_register(H5P_genclass_t *pclass, const char *name, size_t size, } /* 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_close))==NULL) + 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 */ @@ -1995,11 +2026,12 @@ done: 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, - void **initial_value); + 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. - void **initial_value; IN/OUT: The initial value for the property being created. + 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 @@ -2009,11 +2041,12 @@ done: 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, - void **value); + 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. - void **new_value; IN/OUT: The value being set for the property. + 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 @@ -2022,11 +2055,12 @@ done: 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, - void *value); + 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. - void **value; IN/OUT: The value being retrieved for the property. + 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 @@ -2035,10 +2069,11 @@ done: 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, - void *value); + 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 @@ -2047,10 +2082,12 @@ done: 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, void *value); + 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 closed. - void *value; IN: The value of the property being closed. + 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 @@ -2058,9 +2095,11 @@ done: 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, void *value); + 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 @@ -2108,7 +2147,7 @@ H5Pregister(hid_t cls_id, const char *name, size_t size, void *def_value, 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,prp_close))<0) + 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: @@ -2130,6 +2169,8 @@ done: 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 @@ -2151,11 +2192,11 @@ done: 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, - void **value); + 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. - void **new_value; IN/OUT: The value being set for the property. + 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 @@ -2164,11 +2205,12 @@ done: 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, - void *value); + 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. - void **value; IN/OUT: The value being retrieved for the property. + 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 @@ -2177,22 +2219,51 @@ done: 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, - void *value); + 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, + 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 @@ -2226,7 +2297,7 @@ 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_close_func_t prp_close) + H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close) { H5P_genprop_t *new_prop=NULL; /* Temporary property pointer */ H5TB_NODE *prop_node; /* TBBT node holding property */ @@ -2272,7 +2343,7 @@ H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, /* 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_close))==NULL) + 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 */ @@ -2311,6 +2382,7 @@ done: 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 @@ -2332,11 +2404,11 @@ done: 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, - void **value); + 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. - void **new_value; IN/OUT: The value being set for the property. + 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 @@ -2345,11 +2417,12 @@ done: 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, - void *value); + 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. - void **value; IN/OUT: The value being retrieved for the property. + 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 @@ -2358,21 +2431,37 @@ done: 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, - void *value); + 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, void *value); + 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 @@ -2424,7 +2513,7 @@ H5Pinsert(hid_t plist_id, const char *name, size_t size, void *value, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); /* Create the new property list class */ - if ((ret_value=H5P_insert(plist,name,size,value,prp_set,prp_get,prp_delete,prp_copy,prp_close))<0) + 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"); done: @@ -3239,13 +3328,6 @@ H5P_cmp_prop(H5P_genprop_t *prop1, H5P_genprop_t *prop2) if(prop1->size < prop2->size) HGOTO_DONE(-1); if(prop1->size > prop2->size) 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) - if((cmp_value=HDmemcmp(prop1->value,prop2->value,prop1->size))!=0) - HGOTO_DONE(cmp_value); - /* 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); @@ -3271,11 +3353,25 @@ H5P_cmp_prop(H5P_genprop_t *prop1, H5P_genprop_t *prop2) 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() */ @@ -4727,7 +4823,7 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) 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->copy))==NULL) + 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 */ @@ -4809,7 +4905,7 @@ H5P_copy_prop_pclass(H5P_genclass_t *dst_pclass, H5P_genclass_t *src_pclass, con 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->close)<0) + 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: diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index 1b287fb..1c05075 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -74,6 +74,7 @@ typedef struct H5P_genprop_t { H5P_prp_get_func_t get; /* Function to call when a property value is retrieved */ H5P_prp_delete_func_t del; /* Function to call when a property is deleted */ H5P_prp_copy_func_t copy; /* Function to call when a property is copied */ + H5P_prp_compare_func_t cmp; /* Function to call when a property is compared */ H5P_prp_close_func_t close; /* Function to call when a property is closed */ } H5P_genprop_t; diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index bb89ae2..e087624 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -41,7 +41,7 @@ H5_DLL herr_t H5P_set(H5P_genplist_t *plist, const char *name, const void *value H5_DLL 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_close_func_t prp_close); + H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close); 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); @@ -49,7 +49,8 @@ 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, 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_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 65751dc..621524e 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -70,6 +70,7 @@ typedef H5P_prp_cb2_t H5P_prp_set_func_t; typedef H5P_prp_cb2_t H5P_prp_get_func_t; typedef H5P_prp_cb2_t H5P_prp_delete_func_t; typedef H5P_prp_cb1_t H5P_prp_copy_func_t; +typedef int (*H5P_prp_compare_func_t)(const void *value1, const void *value2, size_t size); typedef H5P_prp_cb1_t H5P_prp_close_func_t; /* Define property list iteration function type */ @@ -157,6 +158,7 @@ H5_DLL herr_t H5Punregister(hid_t pclass_id, const char *name); H5_DLL herr_t H5Pclose_class(hid_t plist_id); H5_DLL herr_t H5Pclose(hid_t plist_id); H5_DLL hid_t H5Pcopy(hid_t plist_id); + H5_DLL herr_t H5Pget_version(hid_t plist_id, int *boot/*out*/, int *freelist/*out*/, int *stab/*out*/, int *shhdr/*out*/); diff --git a/test/dsets.c b/test/dsets.c index 185832f..0e56d8e 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -71,6 +71,8 @@ const char *FILENAME[] = { #define DSET_SET_LOCAL_NAME "set_local" #define DSET_SET_LOCAL_NAME_2 "set_local_2" #define DSET_ONEBYTE_SHUF_NAME "onebyte_shuffle" +#define DSET_COMPARE_DCPL_NAME "compare_dcpl" +#define DSET_COMPARE_DCPL_NAME_2 "compare_dcpl_2" #define USER_BLOCK 1024 #define SIXTY_FOUR_KB 65536 @@ -3019,6 +3021,91 @@ error: /*------------------------------------------------------------------------- + * Function: test_compare_dcpl + * + * Purpose: Verifies that if the same DCPL was used to create two + * datasets, the DCPLs retrieved from each dataset should + * compare equal. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Wednesday, January 7, 2004 + * + *------------------------------------------------------------------------- + */ +static herr_t +test_compare_dcpl(hid_t file) +{ + hid_t dsid=(-1); /* Dataset ID */ + hid_t sid=(-1); /* Dataspace ID */ + hid_t dcpl=(-1); /* Dataspace creation property list ID */ + hid_t dcpl1=(-1),dcpl2=(-1); /* Dataspace creation property list IDs from datasets */ + const hsize_t dims[2] = {500, 4096}; /* Dataspace dimensions */ + const hsize_t chunk_dims[2] = {250, 2048}; /* Chunk dimensions */ + + TESTING("comparing dataset creation property lists"); + + /* Create the data space */ + if ((sid = H5Screate_simple(2, dims, NULL))<0) TEST_ERROR + + /* Create dcpl with special filter */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE))<0) TEST_ERROR + if(H5Pset_chunk(dcpl, 2, chunk_dims)<0) TEST_ERROR + + /* Set gzip parameter (if available) */ +#ifdef H5_HAVE_FILTER_DEFLATE + if(H5Pset_deflate (dcpl, 9)<0) TEST_ERROR +#endif /* H5_HAVE_FILTER_DEFLATE */ + + /* Create first dataset */ + if ((dsid = H5Dcreate(file, DSET_COMPARE_DCPL_NAME, H5T_NATIVE_INT, sid, dcpl)) <0) TEST_ERROR + + /* Get copy of dataset's dataset creation property list */ + if ((dcpl1=H5Dget_create_plist(dsid))<0) TEST_ERROR + + /* Close dataset */ + if(H5Dclose (dsid)<0) TEST_ERROR + + /* Create second dataset */ + if ((dsid = H5Dcreate(file, DSET_COMPARE_DCPL_NAME_2, H5T_NATIVE_INT, sid, dcpl)) <0) TEST_ERROR + + /* Get copy of dataset's dataset creation property list */ + if ((dcpl2=H5Dget_create_plist(dsid))<0) TEST_ERROR + + /* Close dataset */ + if(H5Dclose (dsid)<0) TEST_ERROR + + /* Close dataspace */ + if(H5Sclose(sid)<0) TEST_ERROR + + /* Compare dataset creation property lists */ + if(H5Pequal(dcpl1,dcpl2)<=0) TEST_ERROR + + /* Close dataset creation property lists */ + if(H5Pclose(dcpl)<0) TEST_ERROR + if(H5Pclose(dcpl1)<0) TEST_ERROR + if(H5Pclose(dcpl2)<0) TEST_ERROR + + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(dsid); + H5Sclose(sid); + H5Pclose(dcpl); + H5Pclose(dcpl1); + H5Pclose(dcpl2); + } H5E_END_TRY; + return -1; +} /* end test_compare_dcpl() */ + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests the dataset interface (H5D) @@ -3084,6 +3171,7 @@ main(void) nerrors += test_set_local(fapl)<0 ?1:0; #endif /* H5_WANT_H5_V1_4_COMPAT */ nerrors += test_can_apply_szip(file)<0 ?1:0; + nerrors += test_compare_dcpl(file)<0 ?1:0; if (H5Fclose(file)<0) goto error; if (nerrors) goto error; |