From 13e5632d32650ff53190bdc37777277d0ae2913d Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 8 Oct 2009 20:31:36 -0500 Subject: [svn-r17623] Description: Bring "compress group's fractal heap" feature from branch back to trunk. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.6.1 (amazon) in debug mode Mac OS X/32 10.6.1 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- src/H5Dint.c | 6 +- src/H5Dlayout.c | 2 +- src/H5Doh.c | 4 +- src/H5Dprivate.h | 5 +- src/H5G.c | 33 +- src/H5Gdense.c | 5 +- src/H5Gobj.c | 99 ++++- src/H5Goh.c | 75 +++- src/H5Gpkg.h | 10 +- src/H5Gprivate.h | 5 + src/H5Groot.c | 20 +- src/H5Gtraverse.c | 21 +- src/H5HFhdr.c | 19 +- src/H5HFman.c | 22 + src/H5HFpkg.h | 1 + src/H5HFtest.c | 22 +- src/H5Olayout.c | 2 +- src/H5Olinfo.c | 6 +- src/H5Opline.c | 31 +- src/H5Oprivate.h | 19 + src/H5Pdcpl.c | 1020 +---------------------------------------------- src/H5Pocpl.c | 1151 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/H5Ppkg.h | 3 + src/H5Pprivate.h | 11 +- src/H5Ppublic.h | 42 +- src/H5Z.c | 263 +++++++----- src/H5Zpkg.h | 14 - src/H5Zprivate.h | 3 +- src/H5private.h | 5 + test/fheap.c | 4 - test/links.c | 383 ++++++++++++++++++ test/tgenprop.c | 4 +- 32 files changed, 2086 insertions(+), 1224 deletions(-) diff --git a/src/H5Dint.c b/src/H5Dint.c index 7395fba..b92200b 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -178,7 +178,7 @@ H5D_init_interface(void) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve external file list") if(H5P_get(def_dcpl, H5D_CRT_FILL_VALUE_NAME, &H5D_def_dset.dcpl_cache.fill) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value") - if(H5P_get(def_dcpl, H5D_CRT_DATA_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0) + if(H5P_get(def_dcpl, H5O_CRT_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter") /* Reset the "default DXPL cache" information */ @@ -978,7 +978,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, /* Retrieve the properties we need */ pline = &new_dset->shared->dcpl_cache.pline; - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, pline) < 0) + if(H5P_get(dc_plist, H5O_CRT_PIPELINE_NAME, pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve pipeline filter") layout = &new_dset->shared->layout; if(H5P_get(dc_plist, H5D_CRT_LAYOUT_NAME, layout) < 0) @@ -1009,7 +1009,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, /* Set the latest version of the layout, pline & fill messages, if requested */ if(H5F_USE_LATEST_FORMAT(file)) { /* Set the latest version for the I/O pipeline message */ - if(H5Z_set_latest_version(&new_dset->shared->dcpl_cache.pline) < 0) + if(H5O_pline_set_latest_version(&new_dset->shared->dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of I/O filter pipeline") /* Set the latest version for the fill value message */ diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index 8e139ae..d6b7619 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -336,7 +336,7 @@ H5D_layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve message") /* Set the I/O pipeline info in the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &dataset->shared->dcpl_cache.pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &dataset->shared->dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set pipeline") } /* end if */ diff --git a/src/H5Doh.c b/src/H5Doh.c index f2f0c01..becf245 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -155,8 +155,8 @@ H5O_dset_free_copy_file_udata(void *_udata) H5T_close(udata->src_dtype); /* Release copy of dataset's filter pipeline, if it was set */ - if(udata->src_pline) - H5O_msg_free(H5O_PLINE_ID, udata->src_pline); + if(udata->common.src_pline) + H5O_msg_free(H5O_PLINE_ID, udata->common.src_pline); /* Release space for 'copy file' user data */ (void)H5FL_FREE(H5D_copy_file_ud_t, udata); diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index ae427d4..5849598 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -47,7 +47,6 @@ #define H5D_CRT_FILL_VALUE_NAME "fill_value" /* Fill value */ #define H5D_CRT_ALLOC_TIME_STATE_NAME "alloc_time_state" /* Space allocation time state */ #define H5D_CRT_EXT_FILE_LIST_NAME "efl" /* External file list */ -#define H5D_CRT_DATA_PIPELINE_NAME "pline" /* Data filter pipeline */ /* ======== Dataset access property names ======== */ #define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */ @@ -135,15 +134,15 @@ typedef struct H5D_dxpl_cache_t { /* Typedef for cached dataset creation property list information */ typedef struct H5D_dcpl_cache_t { H5O_fill_t fill; /* Fill value info (H5D_CRT_FILL_VALUE_NAME) */ - H5O_pline_t pline; /* I/O pipeline info (H5D_CRT_DATA_PIPELINE_NAME) */ + H5O_pline_t pline; /* I/O pipeline info (H5O_CRT_PIPELINE_NAME) */ H5O_efl_t efl; /* External file list info (H5D_CRT_EXT_FILE_LIST_NAME) */ } H5D_dcpl_cache_t; /* Callback information for copying datasets */ typedef struct H5D_copy_file_ud_t { + H5O_copy_file_ud_common_t common; /* Shared information (must be first) */ struct H5S_extent_t *src_space_extent; /* Copy of dataspace extent for dataset */ H5T_t *src_dtype; /* Copy of datatype for dataset */ - H5O_pline_t *src_pline; /* Copy of filter pipeline for dataet */ } H5D_copy_file_ud_t; diff --git a/src/H5G.c b/src/H5G.c index 2afd837..204245a 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -432,6 +432,7 @@ H5Gget_create_plist(hid_t group_id) H5O_linfo_t linfo; /* Link info message */ htri_t ginfo_exists; htri_t linfo_exists; + htri_t pline_exists; H5G_t *grp = NULL; H5P_genplist_t *gcpl_plist; H5P_genplist_t *new_plist; @@ -481,6 +482,21 @@ H5Gget_create_plist(hid_t group_id) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info") } /* end if */ + /* Check for the group having a pipeline message */ + if((pline_exists = H5O_msg_exists(&(grp->oloc), H5O_PLINE_ID, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") + if(pline_exists) { + H5O_pline_t pline; /* Pipeline message */ + + /* Read the pipeline */ + if(NULL == H5O_msg_read(&(grp->oloc), H5O_PLINE_ID, &pline, H5AC_ind_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline") + + /* Set the pipeline for the property list */ + if(H5P_set(new_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link pipeline") + } /* end if */ + /* Set the return value */ ret_value = new_gcpl_id; @@ -838,9 +854,6 @@ H5G_t * H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id) { H5G_t *grp = NULL; /*new group */ - H5P_genplist_t *gc_plist; /* Property list created */ - H5O_ginfo_t ginfo; /* Group info */ - H5O_linfo_t linfo; /* Link info */ unsigned oloc_init = 0; /* Flag to indicate that the group object location was created successfully */ H5G_t *ret_value; /* Return value */ @@ -857,20 +870,8 @@ H5G_create(H5F_t *file, hid_t gcpl_id, hid_t dxpl_id) if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* Get the property list */ - if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(gcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list") - - /* Get the group info property */ - if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info") - - /* Get the link info property */ - if(H5P_get(gc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info") - /* Create the group object header */ - if(H5G_obj_create(file, dxpl_id, &ginfo, &linfo, gcpl_id, &(grp->oloc)/*out*/) < 0) + if(H5G_obj_create(file, dxpl_id, gcpl_id, &(grp->oloc)/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header") oloc_init = 1; /* Indicate that the object location information is valid */ diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 322b31b..a7c6b9b 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -267,7 +267,8 @@ typedef struct { *------------------------------------------------------------------------- */ herr_t -H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo) +H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, + const H5O_pline_t *pline) { H5HF_create_t fheap_cparam; /* Fractal heap creation parameters */ H5HF_t *fheap; /* Fractal heap handle */ @@ -293,6 +294,8 @@ H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo) fheap_cparam.managed.start_root_rows = H5G_FHEAP_MAN_START_ROOT_ROWS; fheap_cparam.checksum_dblocks = H5G_FHEAP_CHECKSUM_DBLOCKS; fheap_cparam.max_man_size = H5G_FHEAP_MAX_MAN_SIZE; + if(pline) + fheap_cparam.pline = *pline; /* Create fractal heap for storing links */ if(NULL == (fheap = H5HF_create(f, dxpl_id, &fheap_cparam))) diff --git a/src/H5Gobj.c b/src/H5Gobj.c index d2dc607..edc68e4 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -125,20 +125,78 @@ static herr_t H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, *------------------------------------------------------------------------- */ herr_t -H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - const H5O_linfo_t *linfo, hid_t gcpl_id, H5O_loc_t *oloc/*out*/) +H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, H5O_loc_t *oloc/*out*/) +{ + H5P_genplist_t *gc_plist; /* Group creation property list */ + H5O_ginfo_t ginfo; /* Group info */ + H5O_linfo_t linfo; /* Link info */ + H5O_pline_t pline; /* Pipeline */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_obj_create, FAIL) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(oloc); + + /* Get the property list */ + if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(gcpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a property list") + + /* Get the group info property */ + if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") + + /* Get the link info property */ + if(H5P_get(gc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") + + /* Get the pipeline property */ + if(H5P_get(gc_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info") + + /* Call the "real" group creation routine now */ + if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcpl_id, oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create group") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_obj_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_obj_create_real + * + * Purpose: Create an object header for a group and update object location info + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 29 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, + const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id, + H5O_loc_t *oloc/*out*/) { size_t hdr_size; /* Size of object header to request */ hbool_t use_latest_format; /* Flag indicating the new group format should be used */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_obj_create, FAIL) + FUNC_ENTER_NOAPI(H5G_obj_create_real, FAIL) /* * Check arguments. */ HDassert(f); HDassert(ginfo); + HDassert(linfo); + HDassert(pline); HDassert(oloc); /* Check for invalid access request */ @@ -147,7 +205,8 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Check for using the latest version of the group format */ /* (add more checks for creating "new format" groups when needed) */ - if(H5F_USE_LATEST_FORMAT(f) || linfo->track_corder) + if(H5F_USE_LATEST_FORMAT(f) || linfo->track_corder + || (pline && pline->nused)) use_latest_format = TRUE; else use_latest_format = FALSE; @@ -164,6 +223,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, char null_char = '\0'; /* Character for creating null string */ size_t ginfo_size; /* Size of the group info message */ size_t linfo_size; /* Size of the link info message */ + size_t pline_size = 0; /* Size of the pipeline message */ size_t link_size; /* Size of a link message */ /* Calculate message size infomation, for creating group's object header */ @@ -173,6 +233,11 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, ginfo_size = H5O_msg_size_f(f, gcpl_id, H5O_GINFO_ID, ginfo, (size_t)0); HDassert(ginfo_size); + if(pline && pline->nused) { + pline_size = H5O_msg_size_f(f, gcpl_id, H5O_PLINE_ID, pline, (size_t)0); + HDassert(pline_size); + } /* end if */ + lnk.type = H5L_TYPE_HARD; lnk.corder = 0; lnk.corder_valid = linfo->track_corder; @@ -184,6 +249,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Compute size of header to use for creation */ hdr_size = linfo_size + ginfo_size + + pline_size + (ginfo->est_num_entries * link_size); } /* end if */ else @@ -206,6 +272,11 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Insert group info message */ if(H5O_msg_create(oloc, H5O_GINFO_ID, H5O_MSG_FLAG_CONSTANT, 0, ginfo, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") + + /* Insert pipeline message */ + if(pline && pline->nused) + if(H5O_msg_create(oloc, H5O_PLINE_ID, H5O_MSG_FLAG_CONSTANT, 0, pline, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") } /* end if */ else { H5O_stab_t stab; /* Symbol table message */ @@ -217,7 +288,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_obj_create() */ +} /* end H5G_obj_create_real() */ /*------------------------------------------------------------------------- @@ -369,6 +440,8 @@ herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, hbool_t adj_link, hid_t dxpl_id) { + H5O_pline_t tmp_pline; /* Pipeline message */ + H5O_pline_t *pline = NULL; /* Pointer to pipeline message */ H5O_linfo_t linfo; /* Link info message */ htri_t linfo_exists; /* Whether the link info message exists */ hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for insertions or not */ @@ -420,11 +493,21 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, else if(linfo.nlinks < ginfo.max_compact && link_msg_size < H5O_MESG_MAX_SIZE) use_new_dense = FALSE; else { + htri_t pline_exists; /* Whether the pipeline message exists */ H5G_obj_oh_it_ud1_t udata; /* User data for iteration */ H5O_mesg_operator_t op; /* Message operator */ + /* Get the pipeline message, if it exists */ + if((pline_exists = H5O_msg_exists(grp_oloc, H5O_PLINE_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") + if(pline_exists) { + if(NULL == H5O_msg_read(grp_oloc, H5O_PLINE_ID, &tmp_pline, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline") + pline = &tmp_pline; + } /* end if */ + /* The group doesn't currently have "dense" storage for links */ - if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo) < 0) + if(H5G_dense_create(grp_oloc->file, dxpl_id, &linfo, pline) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create 'dense' form of new format group") /* Set up user data for object header message iteration */ @@ -529,6 +612,10 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, } /* end if */ done: + /* Free any space used by the pipeline message */ + if(pline && H5O_msg_reset(H5O_PLINE_ID, pline) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "can't release pipeline") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_obj_insert() */ diff --git a/src/H5Goh.c b/src/H5Goh.c index 0827285..ff75452 100644 --- a/src/H5Goh.c +++ b/src/H5Goh.c @@ -45,6 +45,8 @@ /* Local Prototypes */ /********************/ +static void *H5O_group_get_copy_file_udata(void); +static void H5O_group_free_copy_file_udata(void *udata); static htri_t H5O_group_isa(H5O_t *loc); static hid_t H5O_group_open(const H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id, hbool_t app_ref); @@ -73,8 +75,8 @@ static herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{ H5O_TYPE_GROUP, /* object type */ "group", /* object name, for debugging */ - NULL, /* get 'copy file' user data */ - NULL, /* free 'copy file' user data */ + H5O_group_get_copy_file_udata, /* get 'copy file' user data */ + H5O_group_free_copy_file_udata, /* free 'copy file' user data */ H5O_group_isa, /* "isa" message */ H5O_group_open, /* open an object of this class */ H5O_group_create, /* create an object of this class */ @@ -82,6 +84,75 @@ const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{ H5O_group_bh_info /* get the index & heap info for an object */ }}; +/* Declare the external free list to manage the H5O_ginfo_t struct */ +H5FL_DEFINE(H5G_copy_file_ud_t); + + +/*------------------------------------------------------------------------- + * Function: H5O_group_get_copy_file_udata + * + * Purpose: Allocates the user data needed for copying a group's + * object header from file to file. + * + * Return: Success: Non-NULL pointer to user data + * + * Failure: NULL + * + * Programmer: Neil Fortner + * Thursday, July 30, 2009 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_group_get_copy_file_udata(void) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_group_get_copy_file_udata) + + /* Allocate space for the 'copy file' user data for copying groups. + * Currently this is only a ginfo, so there is no specific struct type for + * this operation. */ + if(NULL == (ret_value = H5FL_CALLOC(H5G_copy_file_ud_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_group_get_copy_file_udata() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_group_free_copy_file_udata + * + * Purpose: Release the user data needed for copying a group's + * object header from file to file. + * + * Return: + * + * Programmer: Neil Fortner + * Thursday, July 30, 2009 + * + *------------------------------------------------------------------------- + */ +static void +H5O_group_free_copy_file_udata(void *_udata) +{ + H5G_copy_file_ud_t *udata = (H5G_copy_file_ud_t *)_udata; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_group_free_copy_file_udata) + + /* Sanity check */ + HDassert(udata); + + /* Free the ginfo struct (including nested data structs) */ + H5O_msg_free(H5O_PLINE_ID, udata->common.src_pline); + + /* Release space for 'copy file' user data (ginfo struct) */ + (void)H5FL_FREE(H5G_copy_file_ud_t, udata); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5O_group_free_copy_file_udata() */ + /*------------------------------------------------------------------------- * Function: H5O_group_isa diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 3d25109..80c4a7b 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -501,7 +501,8 @@ H5_DLL H5G_obj_t H5G_compact_get_type_by_idx(H5O_loc_t *oloc, hid_t dxpl_id, /* Functions that understand "dense" link storage */ H5_DLL herr_t H5G_dense_build_table(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, H5G_link_table_t *ltable); -H5_DLL herr_t H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo); +H5_DLL herr_t H5G_dense_create(H5F_t *f, hid_t dxpl_id, H5O_linfo_t *linfo, + const H5O_pline_t *pline); H5_DLL herr_t H5G_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo, const H5O_link_t *lnk); H5_DLL htri_t H5G_dense_lookup(H5F_t *f, hid_t dxpl_id, @@ -528,8 +529,11 @@ H5_DLL H5G_obj_t H5G_dense_get_type_by_idx(H5F_t *f, hid_t dxpl_id, #endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Functions that understand group objects */ -H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, - const H5O_linfo_t *linfo, hid_t gcpl_id, H5O_loc_t *oloc/*out*/); +H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, hid_t gcpl_id, + H5O_loc_t *oloc/*out*/); +H5_DLL herr_t H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, + const H5O_linfo_t *linfo, const H5O_pline_t *pline, hid_t gcpl_id, + H5O_loc_t *oloc/*out*/); H5_DLL htri_t H5G_obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo, hid_t dxpl_id); H5_DLL herr_t H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index ff20fe6..526fa82 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -141,6 +141,11 @@ typedef struct { H5G_name_t *path; /* Group hierarchy path */ } H5G_loc_t; +/* Callback information for copying groups */ +typedef struct H5G_copy_file_ud_t { + H5O_copy_file_ud_common_t common; /* Shared information (must be first) */ +} H5G_copy_file_ud_t; + typedef struct H5G_t H5G_t; typedef struct H5G_shared_t H5G_shared_t; typedef struct H5G_entry_t H5G_entry_t; diff --git a/src/H5Groot.c b/src/H5Groot.c index 5d07142..7dc98d1 100644 --- a/src/H5Groot.c +++ b/src/H5Groot.c @@ -137,25 +137,9 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) * with a hard link count of one since it's pointed to by the superblock. */ if(create_root) { - H5P_genplist_t *fc_plist; /* File creation property list */ - H5O_ginfo_t ginfo; /* Group info parameters */ - H5O_linfo_t linfo; /* Link info parameters */ - - /* Get the file creation property list */ - /* (Which is a sub-class of the group creation property class) */ - if(NULL == (fc_plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - /* Get the group info property */ - if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info") - - /* Get the link info property */ - if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") - /* Create root group */ - if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0) + /* (Pass the FCPL which is a sub-class of the group creation property class) */ + if(H5G_obj_create(f, dxpl_id, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") if(1 != H5O_link(root_loc.oloc, 1, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 87ebc74..4c287d5 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -711,12 +711,15 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, if(target & H5G_CRT_INTMD_GROUP) { const H5O_ginfo_t def_ginfo = H5G_CRT_GROUP_INFO_DEF; /* Default group info settings */ const H5O_linfo_t def_linfo = H5G_CRT_LINK_INFO_DEF; /* Default link info settings */ + const H5O_pline_t def_pline = H5O_CRT_PIPELINE_DEF; /* Default filter pipeline settings */ H5O_ginfo_t par_ginfo; /* Group info settings for parent group */ H5O_linfo_t par_linfo; /* Link info settings for parent group */ + H5O_pline_t par_pline; /* Filter pipeline settings for parent group */ H5O_linfo_t tmp_linfo; /* Temporary link info settings */ htri_t exists; /* Whether a group or link info message exists */ const H5O_ginfo_t *ginfo; /* Group info settings for new group */ const H5O_linfo_t *linfo; /* Link info settings for new group */ + const H5O_pline_t *pline; /* Filter pipeline settings for new group */ /* Check for the parent group having a group info message */ /* (OK if not found) */ @@ -752,9 +755,25 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Use default link info settings */ linfo = &def_linfo; + /* Check for the parent group having a filter pipeline message */ + /* (OK if not found) */ + if((exists = H5O_msg_exists(grp_loc.oloc, H5O_PLINE_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") + if(exists) { + /* Get the filter pipeline for parent group */ + if(NULL == H5O_msg_read(grp_loc.oloc, H5O_PLINE_ID, &par_pline, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "filter pipeline message not present") + + /* Use parent filter pipeline settings */ + pline = &par_pline; + } /* end if */ + else + /* Use default filter pipeline settings */ + pline = &def_pline; + /* Create the intermediate group */ /* XXX: Should we allow user to control the group creation params here? -QAK */ - if(H5G_obj_create(grp_oloc.file, dxpl_id, ginfo, linfo, H5P_GROUP_CREATE_DEFAULT, obj_loc.oloc/*out*/) < 0) + if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, pline, H5P_GROUP_CREATE_DEFAULT, obj_loc.oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") /* Insert new group into current group's symbol table */ diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index d1f2675..3762af6 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -423,6 +423,17 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) * length is already set in that case (its stored in the header on disk)) */ if(cparam->pline.nused > 0) { + /* Check if the filters in the DCPL can be applied to this dataset */ + if(H5Z_can_apply_direct(&(cparam->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "I/O filters can't operate on this heap") + + /* Mark the filters as checked */ + hdr->checked_filters = TRUE; + + /* Make the "set local" filter callbacks for this dataset */ + if(H5Z_set_local_direct(&(cparam->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "unable to set local filter parameters") + /* Copy the I/O filter pipeline from the creation parameters to the header */ if(NULL == H5O_msg_copy(H5O_PLINE_ID, &(cparam->pline), &(hdr->pline))) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, HADDR_UNDEF, "can't copy I/O filter pipeline") @@ -430,7 +441,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Pay attention to the latest version flag for the file */ if(H5F_USE_LATEST_FORMAT(hdr->f)) /* Set the latest version for the I/O pipeline message */ - if(H5Z_set_latest_version(&(hdr->pline)) < 0) + if(H5O_pline_set_latest_version(&(hdr->pline)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, HADDR_UNDEF, "can't set latest version of I/O filter pipeline") /* Compute the I/O filters' encoded size */ @@ -446,10 +457,14 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", FUNC, hdr->filter_len); + 4 /* Size of filter mask for filtered root direct block */ + hdr->filter_len; /* Size of encoded I/O filter info */ } /* end if */ - else + else { /* Set size of header on disk */ hdr->heap_size = H5HF_HEADER_SIZE(hdr); + /* Mark filters as checked, for performance reasons */ + hdr->checked_filters = TRUE; + } /* end else */ + /* Set the length of IDs in the heap */ /* (This code is not in the "finish init phase" routines because those * routines are also called from the cache 'load' callback, and the ID diff --git a/src/H5HFman.c b/src/H5HFman.c index 5bdc769..3fb0cfb 100644 --- a/src/H5HFman.c +++ b/src/H5HFman.c @@ -44,6 +44,19 @@ /* Local Macros */ /****************/ +/* Macro to check if we can apply all filters in the pipeline. Use whenever + * performing a modification operation */ + #define H5HF_MAN_WRITE_CHECK_PLINE(HDR) \ +{ \ + if(!((HDR)->checked_filters)) { \ + if((HDR)->pline.nused) \ + if(H5Z_can_apply_direct(&((HDR)->pline)) < 0) \ + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "I/O filters can't operate on this heap") \ + \ + (HDR)->checked_filters = TRUE; \ + } /* end if */ \ +} + /******************/ /* Local Typedefs */ @@ -116,6 +129,9 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size); HDassert(obj); HDassert(id); + /* Check pipeline */ + H5HF_MAN_WRITE_CHECK_PLINE(hdr) + /* Look for free space */ if((node_found = H5HF_space_find(hdr, dxpl_id, (hsize_t)obj_size, &sec_node)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap") @@ -272,6 +288,9 @@ H5HF_man_op_real(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, /* Set the access mode for the direct block */ if(op_flags & H5HF_OP_MODIFY) { + /* Check pipeline */ + H5HF_MAN_WRITE_CHECK_PLINE(hdr) + dblock_access = H5AC_WRITE; dblock_cache_flags = H5AC__DIRTIED_FLAG; } /* end if */ @@ -533,6 +552,9 @@ H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) HDassert(hdr); HDassert(id); + /* Check pipeline */ + H5HF_MAN_WRITE_CHECK_PLINE(hdr) + /* Skip over the flag byte */ id++; diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index 3fe3ad2..4f2dbc3 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -354,6 +354,7 @@ typedef struct H5HF_hdr_t { uint8_t huge_id_size; /* Size of 'huge' heap IDs (in bytes) */ uint8_t heap_off_size; /* Size of heap offsets (in bytes) */ uint8_t heap_len_size; /* Size of heap ID lengths (in bytes) */ + hbool_t checked_filters; /* TRUE if pipeline passes can_apply checks */ } H5HF_hdr_t; /* Common indirect block doubling table entry */ diff --git a/src/H5HFtest.c b/src/H5HFtest.c index 76611e9..30adf96 100644 --- a/src/H5HFtest.c +++ b/src/H5HFtest.c @@ -133,8 +133,26 @@ H5HF_cmp_cparam_test(const H5HF_create_t *cparam1, const H5HF_create_t *cparam2) HDassert(cparam2); /* Compare doubling table parameters */ - if((ret_value = HDmemcmp(&(cparam1->managed), &(cparam2->managed), sizeof(H5HF_dtable_cparam_t)))) - HGOTO_DONE(ret_value) + if(cparam1->managed.width < cparam2->managed.width) + HGOTO_DONE(-1) + else if(cparam1->managed.width > cparam2->managed.width) + HGOTO_DONE(1) + if(cparam1->managed.start_block_size < cparam2->managed.start_block_size) + HGOTO_DONE(-1) + else if(cparam1->managed.start_block_size > cparam2->managed.start_block_size) + HGOTO_DONE(1) + if(cparam1->managed.max_direct_size < cparam2->managed.max_direct_size) + HGOTO_DONE(-1) + else if(cparam1->managed.max_direct_size > cparam2->managed.max_direct_size) + HGOTO_DONE(1) + if(cparam1->managed.max_index < cparam2->managed.max_index) + HGOTO_DONE(-1) + else if(cparam1->managed.max_index > cparam2->managed.max_index) + HGOTO_DONE(1) + if(cparam1->managed.start_root_rows < cparam2->managed.start_root_rows) + HGOTO_DONE(-1) + else if(cparam1->managed.start_root_rows > cparam2->managed.start_root_rows) + HGOTO_DONE(1) /* Compare other general parameters for heap */ if(cparam1->max_man_size < cparam2->max_man_size) diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 39905be..e4257c9 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -622,7 +622,7 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, case H5D_CHUNKED: if(H5D_chunk_is_space_alloc(&layout_src->storage)) { /* Create chunked layout */ - if(H5D_chunk_copy(file_src, &layout_src->storage.u.chunk, &layout_src->u.chunk, file_dst, &layout_dst->storage.u.chunk, udata->src_space_extent, udata->src_dtype, udata->src_pline, cpy_info, dxpl_id) < 0) + if(H5D_chunk_copy(file_src, &layout_src->storage.u.chunk, &layout_src->u.chunk, file_dst, &layout_dst->storage.u.chunk, udata->src_space_extent, udata->src_dtype, udata->common.src_pline, cpy_info, dxpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy chunked storage") } /* end if */ break; diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index 5ba237a..ba5ec56 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -377,11 +377,12 @@ done: */ static void * H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, - hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, + hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id) { H5O_linfo_t *linfo_src = (H5O_linfo_t *) native_src; H5O_linfo_t *linfo_dst = NULL; + H5G_copy_file_ud_t *udata = (H5G_copy_file_ud_t *) _udata; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_linfo_copy_file) @@ -411,7 +412,8 @@ H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst, * dense link storage components and use those - QAK) */ if(H5F_addr_defined(linfo_src->fheap_addr)) { - if(H5G_dense_create(file_dst, dxpl_id, linfo_dst) < 0) + /* Create the dense link storage */ + if(H5G_dense_create(file_dst, dxpl_id, linfo_dst, udata->common.src_pline) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create 'dense' form of new format group") } /* end if */ } /* end else */ diff --git a/src/H5Opline.c b/src/H5Opline.c index cc00996..0a50963 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -572,7 +572,7 @@ H5O_pline_pre_copy_file(H5F_t UNUSED *file_src, const void *mesg_src, hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info, void *_udata) { const H5O_pline_t *pline_src = (const H5O_pline_t *)mesg_src; /* Source datatype */ - H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ + H5O_copy_file_ud_common_t *udata = (H5O_copy_file_ud_common_t *)_udata; /* Object copying user data */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_pline_pre_copy_file) @@ -580,7 +580,7 @@ H5O_pline_pre_copy_file(H5F_t UNUSED *file_src, const void *mesg_src, /* check args */ HDassert(pline_src); - /* If the user data is non-NULL, assume we are copying a dataset + /* If the user data is non-NULL, assume we are copying a dataset or group * and make a copy of the filter pipeline for later in * the object copying process. */ @@ -665,3 +665,30 @@ H5O_pline_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *mesg, FILE *s FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_pline_debug() */ + +/*------------------------------------------------------------------------- + * Function: H5O_pline_set_latest_version + * + * Purpose: Set the encoding for a I/O filter pipeline to the latest version. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, July 24, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_pline_set_latest_version(H5O_pline_t *pline) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5O_pline_set_latest_version) + + /* Sanity check */ + HDassert(pline); + + /* Set encoding of I/O pipeline to latest version */ + pline->version = H5O_PLINE_VERSION_LATEST; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_pline_set_latest_version() */ + diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index a47a40d..5199c20 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -88,6 +88,8 @@ typedef struct H5O_t H5O_t; #define H5O_CRT_ATTR_MAX_COMPACT_NAME "max compact attr" /* Max. # of attributes to store compactly */ #define H5O_CRT_ATTR_MIN_DENSE_NAME "min dense attr" /* Min. # of attributes to store densely */ #define H5O_CRT_OHDR_FLAGS_NAME "object header flags" /* Object header flags */ +#define H5O_CRT_PIPELINE_NAME "pline" /* Filter pipeline */ +#define H5O_CRT_PIPELINE_DEF {{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL} #ifdef H5O_ENABLE_BOGUS #define H5O_BOGUS_MSG_FLAGS_NAME "bogus msg flags" /* Flags for 'bogus' message */ #define H5O_BOGUS_MSG_FLAGS_SIZE sizeof(uint8_t) @@ -448,6 +450,20 @@ typedef struct H5O_ginfo_t { * Filter pipeline message. * (Data structure in memory) */ + +/* The initial version of the format */ +#define H5O_PLINE_VERSION_1 1 + +/* This version encodes the message fields more efficiently */ +/* (Drops the reserved bytes, doesn't align the name and doesn't encode the + * filter name at all if it's a filter provided by the library) + */ +#define H5O_PLINE_VERSION_2 2 + +/* The latest version of the format. Look through the 'encode' and 'size' + * callbacks for places to change when updating this. */ +#define H5O_PLINE_VERSION_LATEST H5O_PLINE_VERSION_2 + typedef struct H5O_pline_t { H5O_shared_t sh_loc; /* Shared message info (must be first) */ @@ -701,6 +717,9 @@ H5_DLL herr_t H5O_fill_set_latest_version(H5O_fill_t *fill); H5_DLL herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg); +/* Filter pipeline operators */ +H5_DLL herr_t H5O_pline_set_latest_version(H5O_pline_t *pline); + /* Shared message operators */ H5_DLL herr_t H5O_set_shared(H5O_shared_t *dst, const H5O_shared_t *src); diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 2f7e280..84ef3d4 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -87,10 +87,6 @@ #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 H5P_dcrt_ext_file_list_cmp -/* Definitions for data filter pipeline */ -#define H5D_CRT_DATA_PIPELINE_SIZE sizeof(H5O_pline_t) -#define H5D_CRT_DATA_PIPELINE_DEF {{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL} -#define H5D_CRT_DATA_PIPELINE_CMP H5P_dcrt_data_pipeline_cmp /******************/ @@ -121,7 +117,6 @@ static herr_t H5P_dcrt_close(hid_t dxpl_id, void *close_data); /* Property callbacks */ static int H5P_dcrt_layout_cmp(const void *value1, const void *value2, size_t size); static int H5P_dcrt_ext_file_list_cmp(const void *value1, const void *value2, size_t size); -static int H5P_dcrt_data_pipeline_cmp(const void *value1, const void *value2, size_t size); /*********************/ @@ -183,7 +178,6 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass) H5O_fill_t fill = H5D_CRT_FILL_VALUE_DEF; /* Default fill value */ unsigned alloc_time_state = H5D_CRT_ALLOC_TIME_STATE_DEF; /* Default allocation time state */ H5O_efl_t efl = H5D_CRT_EXT_FILE_LIST_DEF; /* Default external file list */ - H5O_pline_t pline = H5D_CRT_DATA_PIPELINE_DEF; /* Default I/O pipeline setting */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_dcrt_reg_prop) @@ -204,10 +198,6 @@ H5P_dcrt_reg_prop(H5P_genclass_t *pclass) if(H5P_register(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(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") - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_dcrt_reg_prop() */ @@ -234,7 +224,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) { H5O_fill_t src_fill, dst_fill; /* Source & destination fill values */ H5O_efl_t src_efl, dst_efl; /* Source & destination external file lists */ - H5O_pline_t src_pline, dst_pline; /* Source & destination I/O pipelines */ H5O_layout_t src_layout, dst_layout; /* Source & destination layout */ H5P_genplist_t *src_plist; /* Pointer to source property list */ H5P_genplist_t *dst_plist; /* Pointer to destination property list */ @@ -257,8 +246,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value") if(H5P_get(src_plist, H5D_CRT_EXT_FILE_LIST_NAME, &src_efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list") - if(H5P_get(src_plist, H5D_CRT_DATA_PIPELINE_NAME, &src_pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") /* Make copy of layout */ if(NULL == H5O_msg_copy(H5O_LAYOUT_ID, &src_layout, &dst_layout)) @@ -313,10 +300,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) dst_efl.slot[i].name_offset = 0; } /* end if */ - /* Make copy of data pipeline */ - if(NULL == H5O_msg_copy(H5O_PLINE_ID, &src_pline, &dst_pline)) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy data pipeline") - /* Set the layout, fill value, external file list, and data pipeline * properties for the destination property list */ @@ -326,8 +309,6 @@ H5P_dcrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value") if(H5P_set(dst_plist, H5D_CRT_EXT_FILE_LIST_NAME, &dst_efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set external file list") - if(H5P_set(dst_plist, H5D_CRT_DATA_PIPELINE_NAME, &dst_pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") done: FUNC_LEAVE_NOAPI(ret_value) @@ -355,7 +336,6 @@ H5P_dcrt_close(hid_t dcpl_id, void UNUSED *close_data) { H5O_fill_t fill; /* Fill value */ H5O_efl_t efl; /* External file list */ - H5O_pline_t pline; /* I/O pipeline */ H5P_genplist_t *plist; /* Property list */ herr_t ret_value = SUCCEED; /* Return value */ @@ -371,17 +351,12 @@ H5P_dcrt_close(hid_t dcpl_id, void UNUSED *close_data) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value") if(H5P_get(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list") - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - /* Clean up any values set for the fill-value, external file-list and - * data pipeline */ + /* Clean up any values set for the fill-value and external file-list */ if(H5O_msg_reset(H5O_FILL_ID, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release fill info") if(H5O_msg_reset(H5O_EFL_ID, &efl) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release external file list info") - if(H5O_msg_reset(H5O_PLINE_ID, &pline) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release pipeline info") done: FUNC_LEAVE_NOAPI(ret_value) @@ -600,92 +575,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5P_dcrt_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 - * - *------------------------------------------------------------------------- - */ -static int -H5P_dcrt_data_pipeline_cmp(const void *_pline1, const void *_pline2, size_t UNUSED size) -{ - const H5O_pline_t *pline1 = (const H5O_pline_t *)_pline1, /* Create local aliases for values */ - *pline2 = (const H5O_pline_t *)_pline2; - int cmp_value; /* Value from comparison */ - herr_t ret_value = 0; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_dcrt_data_pipeline_cmp) - - /* Sanity check */ - HDassert(pline1); - HDassert(pline2); - HDassert(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->nused < pline2->nused) HGOTO_DONE(-1); - if(pline1->nused > pline2->nused) 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->nused > 0) { - size_t u; /* Local index variable */ - - /* Loop through all filters, comparing them */ - for(u = 0; u < pline1->nused; u++) { - /* Check the ID of the filter */ - if(pline1->filter[u].id < pline2->filter[u].id) HGOTO_DONE(-1); - if(pline1->filter[u].id > pline2->filter[u].id) HGOTO_DONE(1); - - /* Check the flags for the filter */ - if(pline1->filter[u].flags < pline2->filter[u].flags) HGOTO_DONE(-1); - if(pline1->filter[u].flags > pline2->filter[u].flags) HGOTO_DONE(1); - - /* Check the name of the filter */ - if(pline1->filter[u].name == NULL && pline2->filter[u].name != NULL) HGOTO_DONE(-1); - if(pline1->filter[u].name != NULL && pline2->filter[u].name == NULL) HGOTO_DONE(1); - if(pline1->filter[u].name != NULL) - if((cmp_value = HDstrcmp(pline1->filter[u].name, pline2->filter[u].name)) != 0) - HGOTO_DONE(cmp_value); - - /* Check the number of parameters for the filter */ - if(pline1->filter[u].cd_nelmts < pline2->filter[u].cd_nelmts) HGOTO_DONE(-1); - if(pline1->filter[u].cd_nelmts > pline2->filter[u].cd_nelmts) HGOTO_DONE(1); - - /* Check the filter parameter information */ - if(pline1->filter[u].cd_values == NULL && pline2->filter[u].cd_values != NULL) HGOTO_DONE(-1); - if(pline1->filter[u].cd_values != NULL && pline2->filter[u].cd_values == NULL) HGOTO_DONE(1); - if(pline1->filter[u].cd_values != NULL && pline1->filter[u].cd_nelmts > 0) { - size_t v; /* Local index variable */ - - /* Loop through all parameters, comparing them */ - for(v = 0; v < pline1->filter[u].cd_nelmts; v++) { - /* Check each parameter for the filter */ - if(pline1->filter[u].cd_values[v] < pline2->filter[u].cd_values[v]) HGOTO_DONE(-1); - if(pline1->filter[u].cd_values[v] > pline2->filter[u].cd_values[v]) HGOTO_DONE(1); - } /* end for */ - } /* end if */ - } /* end for */ - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_dcrt_data_pipeline_cmp() */ - - -/*------------------------------------------------------------------------- * Function: H5P_set_layout * * Purpose: Sets the layout of raw data in the file. @@ -1254,700 +1143,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5P_modify_filter - * - * Purpose: Modifies the specified FILTER in the - * transient or permanent output filter pipeline - * depending on whether PLIST is a dataset creation or dataset - * transfer property list. The FLAGS argument specifies certain - * general properties of the filter and is documented below. - * The CD_VALUES is an array of CD_NELMTS integers which are - * auxiliary data for the filter. The integer vlues will be - * stored in the dataset object header as part of the filter - * information. - * - * The FLAGS argument is a bit vector of the following fields: - * - * H5Z_FLAG_OPTIONAL(0x0001) - * If this bit is set then the filter is optional. If the - * filter fails during an H5Dwrite() operation then the filter - * is just excluded from the pipeline for the chunk for which it - * failed; the filter will not participate in the pipeline - * during an H5Dread() of the chunk. If this bit is clear and - * the filter fails then the entire I/O operation fails. - * If this bit is set but encoding is disabled for a filter, - * attempting to write will generate an error. - * - * Note: This function currently supports only the permanent filter - * pipeline. That is, PLIST_ID must be a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Wednesday, October 17, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned flags, - size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/]) -{ - H5O_pline_t pline; - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_NOAPI(H5P_modify_filter, FAIL) - - /* Get the pipeline property to append to */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Modify the filter parameters of the I/O pipeline */ - if(H5Z_modify(&pline, filter, flags, cd_nelmts, cd_values) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") - - /* Put the I/O pipeline information back into the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_modify_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pmodify_filter - * - * Purpose: Modifies the specified FILTER in the - * transient or permanent output filter pipeline - * depending on whether PLIST is a dataset creation or dataset - * transfer property list. The FLAGS argument specifies certain - * general properties of the filter and is documented below. - * The CD_VALUES is an array of CD_NELMTS integers which are - * auxiliary data for the filter. The integer vlues will be - * stored in the dataset object header as part of the filter - * information. - * - * The FLAGS argument is a bit vector of the following fields: - * - * H5Z_FLAG_OPTIONAL(0x0001) - * If this bit is set then the filter is optional. If the - * filter fails during an H5Dwrite() operation then the filter - * is just excluded from the pipeline for the chunk for which it - * failed; the filter will not participate in the pipeline - * during an H5Dread() of the chunk. If this bit is clear and - * the filter fails then the entire I/O operation fails. - * If this bit is set but encoding is disabled for a filter, - * attempting to write will generate an error. - * - * Note: This function currently supports only the permanent filter - * pipeline. That is, PLIST_ID must be a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Friday, April 5, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, - size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pmodify_filter, FAIL) - H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); - - /* Check args */ - if (filter<0 || filter>H5Z_FILTER_MAX) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") - if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") - if (cd_nelmts>0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Modify the filter parameters of the I/O pipeline */ - if(H5P_modify_filter(plist, filter, flags, cd_nelmts, cd_values) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't modify filter") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pmodify_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pset_filter - * - * Purpose: Adds the specified FILTER and corresponding properties to the - * end of the transient or permanent output filter pipeline - * depending on whether PLIST is a dataset creation or dataset - * transfer property list. The FLAGS argument specifies certain - * general properties of the filter and is documented below. - * The CD_VALUES is an array of CD_NELMTS integers which are - * auxiliary data for the filter. The integer vlues will be - * stored in the dataset object header as part of the filter - * information. - * - * The FLAGS argument is a bit vector of the following fields: - * - * H5Z_FLAG_OPTIONAL(0x0001) - * If this bit is set then the filter is optional. If the - * filter fails during an H5Dwrite() operation then the filter - * is just excluded from the pipeline for the chunk for which it - * failed; the filter will not participate in the pipeline - * during an H5Dread() of the chunk. If this bit is clear and - * the filter fails then the entire I/O operation fails. - * If this bit is set but encoding is disabled for a filter, - * attempting to write will generate an error. - * - * Note: This function currently supports only the permanent filter - * pipeline. That is, PLIST_ID must be a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - * Modifications: - * - * Raymond Lu - * Tuesday, October 2, 2001 - * Changed the way to check parameter and set property for - * generic property list. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, - size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset_filter, FAIL) - H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); - - /* Check args */ - if (filter<0 || filter>H5Z_FILTER_MAX) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") - if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") - if (cd_nelmts>0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get the pipeline property to append to */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Add the filter to the I/O pipeline */ - if(H5Z_append(&pline, filter, flags, cd_nelmts, cd_values) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") - - /* Put the I/O pipeline information back into the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") - -done: - FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_nfilters - * - * Purpose: Returns the number of filters in the permanent or transient - * pipeline depending on whether PLIST_ID is a dataset creation - * or dataset transfer property list. In each pipeline the - * filters are numbered from zero through N-1 where N is the - * value returned by this function. During output to the file - * the filters of a pipeline are applied in increasing order - * (the inverse is true for input). - * - * Note: Only permanent filters are supported at this time. - * - * Return: Success: Number of filters or zero if there are none. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Tuesday, August 4, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5Pget_nfilters(hid_t plist_id) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - int ret_value; /* return value */ - - FUNC_ENTER_API(H5Pget_nfilters, FAIL) - H5TRACE1("Is", "i", plist_id); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get value */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Set return value */ - ret_value=(int)(pline.nused); - -done: - FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5P_get_filter - * - * Purpose: Internal component of H5Pget_filter & H5Pget_filter_id - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, October 23, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5P_get_filter(const H5Z_filter_info_t *filter, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, - unsigned *filter_config /*out*/) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_filter) - - /* Check arguments */ - HDassert(filter); - - /* Filter flags */ - if(flags) - *flags = filter->flags; - - /* Filter parameters */ - if(cd_values) { - size_t i; /* Local index variable */ - - for(i = 0; i < filter->cd_nelmts && i < *cd_nelmts; i++) - cd_values[i] = filter->cd_values[i]; - } /* end if */ - - /* Number of filter parameters */ - if(cd_nelmts) - *cd_nelmts = filter->cd_nelmts; - - /* Filter name */ - if(namelen > 0 && name) { - const char *s = filter->name; - - /* If there's no name on the filter, use the class's filter name */ - if(!s) { - H5Z_class2_t *cls = H5Z_find(filter->id); - - if(cls) - s = cls->name; - } /* end if */ - - /* Check for actual name */ - if(s) { - HDstrncpy(name, s, namelen); - name[namelen - 1] = '\0'; - } /* end if */ - else { - /* Check for unknown library filter */ - /* (probably from a future version of the library) */ - if(filter->id < 256) { - HDstrncpy(name, "Unknown library filter", namelen); - name[namelen - 1] = '\0'; - } /* end if */ - else - name[0] = '\0'; - } /* end if */ - } /* end if */ - - /* Filter configuration (assume filter ID has already been checked) */ - if(filter_config) - H5Zget_filter_info(filter->id, filter_config); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5P_get_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter2 - * - * Purpose: This is the query counterpart of H5Pset_filter() and returns - * information about a particular filter number in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. FILTER_CONFIG is a bit - * field contaning encode/decode flags from H5Zpublic.h. The IDX - * should be a value between zero and N-1 as described for - * H5Pget_nfilters() and the function will return failure if the - * filter number is out of range. - * - * Return: Success: Filter identification number. - * - * Failure: H5Z_FILTER_ERROR (Negative) - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - *------------------------------------------------------------------------- - */ -H5Z_filter_t -H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, - unsigned *filter_config /*out*/) -{ - H5O_pline_t pline; /* Filter pipeline */ - const H5Z_filter_info_t *filter; /* Pointer to filter information */ - H5P_genplist_t *plist; /* Property list pointer */ - H5Z_filter_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pget_filter2, H5Z_FILTER_ERROR) - H5TRACE8("Zf", "iIux*zxzxx", plist_id, idx, flags, cd_nelmts, cd_values, - namelen, name, filter_config); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") - - /* Check more args */ - if(idx >= pline.nused) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") - - /* Set pointer to particular filter to query */ - filter = &pline.filter[idx]; - - /* Get filter information */ - if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") - - /* Set return value */ - ret_value = filter->id; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter2() */ - - -/*------------------------------------------------------------------------- - * Function: H5P_get_filter_by_id - * - * Purpose: This is an additional query counterpart of H5Pset_filter() and - * returns information about a particular filter in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. FILTER_CONFIG is a bit - * field contaning encode/decode flags from H5Zpublic.h. The ID - * should be the filter ID to retrieve the parameters for. If the - * filter is not set for the property list, an error will be returned. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * Wednesday, October 17, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, unsigned *filter_config) -{ - H5O_pline_t pline; /* Filter pipeline */ - H5Z_filter_info_t *filter; /* Pointer to filter information */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5P_get_filter_by_id, FAIL) - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Get pointer to filter in pipeline */ - if(NULL == (filter = H5Z_filter_info(&pline, id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid") - - /* Get filter information */ - if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_get_filter_by_id() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter_by_id2 - * - * Purpose: This is an additional query counterpart of H5Pset_filter() and - * returns information about a particular filter in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. FILTER_CONFIG is a bit - * field contaning encode/decode flags from H5Zpublic.h. The ID - * should be the filter ID to retrieve the parameters for. If the - * filter is not set for the property list, an error will be returned. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, April 5, 2003 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/, unsigned *filter_config) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pget_filter_by_id2, FAIL) - H5TRACE8("e", "iZfx*zxzx*Iu", plist_id, id, flags, cd_nelmts, cd_values, - namelen, name, filter_config); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get filter info */ - if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter_by_id2() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pall_filters_avail - * - * Purpose: This is a query routine to verify that all the filters set - * in the dataset creation property list are available currently. - * - * Return: Success: TRUE if all filters available, FALSE if one or - * more filters not currently available. - * Failure: FAIL on error - * - * Programmer: Quincey Koziol - * Tuesday, April 8, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5Pall_filters_avail(hid_t plist_id) -{ - H5P_genplist_t *plist; /* Property list pointer */ - H5O_pline_t pline; /* Filter pipeline */ - htri_t ret_value; /* Return value */ - - FUNC_ENTER_API(H5Pall_filters_avail, FAIL) - H5TRACE1("t", "i", plist_id); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Check if all filters are available */ - if((ret_value = H5Z_all_filters_avail(&pline)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't check pipeline information") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pall_filters_avail() */ - - -/*------------------------------------------------------------------------- - * Function: H5Premove_filter - * - * Purpose: Deletes a filter from the dataset creation property list; - * deletes all filters if FILTER is H5Z_FILTER_NONE - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Pedro Vicente - * January 26, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Premove_filter(hid_t plist_id, H5Z_filter_t filter) -{ - H5P_genplist_t *plist; /* Property list pointer */ - H5O_pline_t pline; /* Filter pipeline */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Premove_filter, FAIL) - H5TRACE2("e", "iZf", plist_id, filter); - - /* Get the property list structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - - /* Check if there are any filters */ - if (pline.filter) { - /* Delete filter */ - if(H5Z_delete(&pline, filter) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't delete filter") - - /* Put the I/O pipeline information back into the property list */ - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") - } /* end if */ - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Premove_filter() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pset_deflate - * - * Purpose: Sets the compression method for a permanent or transient - * filter pipeline (depending on whether PLIST_ID is a dataset - * creation or transfer property list) to H5Z_FILTER_DEFLATE - * and the compression level to LEVEL which should be a value - * between zero and nine, inclusive. Lower compression levels - * are faster but result in less compression. This is the same - * algorithm as used by the GNU gzip program. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - * Modifications: - * - * Raymond Lu - * Tuesday, October 2, 2001 - * Changed the way to check parameter and set property for - * generic property list. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_deflate(hid_t plist_id, unsigned level) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset_deflate, FAIL) - H5TRACE2("e", "iIu", plist_id, level); - - /* Check arguments */ - if(level>9) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level") - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Add the filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - if(H5Z_append(&pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &level) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pset_deflate() */ - - -/*------------------------------------------------------------------------- * Function: H5Pset_szip * * Purpose: Sets the compression method for a permanent or transient @@ -2014,11 +1209,11 @@ H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block) cd_values[1]=pixels_per_block; /* Add the filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_SZIP, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add szip filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2061,11 +1256,11 @@ H5Pset_shuffle(hid_t plist_id) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Add the filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_SHUFFLE, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to shuffle the data") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2107,11 +1302,11 @@ H5Pset_nbit(hid_t plist_id) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Add the nbit filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_NBIT, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add nbit filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2186,11 +1381,11 @@ H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_fac cd_values[1] = (unsigned)scale_factor; /* Add the scaleoffset filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") if(H5Z_append(&pline, H5Z_FILTER_SCALEOFFSET, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add scaleoffset filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") done: @@ -2199,48 +1394,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Pset_fletcher32 - * - * Purpose: Sets Fletcher32 checksum of EDC for a dataset creation - * property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * Dec 19, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_fletcher32(hid_t plist_id) -{ - H5O_pline_t pline; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset_fletcher32, FAIL) - H5TRACE1("e", "i", plist_id); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Add the Fletcher32 checksum as a filter */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") - if(H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline") - if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pset_fletcher32() */ - - -/*------------------------------------------------------------------------- * Function: H5Pset_fill_value * * Purpose: Set the fill value for a dataset creation property list. The @@ -2812,158 +1965,3 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_fill_time() */ -#ifndef H5_NO_DEPRECATED_SYMBOLS - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter1 - * - * Purpose: This is the query counterpart of H5Pset_filter() and returns - * information about a particular filter number in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. The IDX - * should be a value between zero and N-1 as described for - * H5Pget_nfilters() and the function will return failure if the - * filter number is out of range. - * - * Return: Success: Filter identification number. - * - * Failure: H5Z_FILTER_ERROR (Negative) - * - * Programmer: Robb Matzke - * Wednesday, April 15, 1998 - * - *------------------------------------------------------------------------- - */ -H5Z_filter_t -H5Pget_filter1(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/) -{ - H5O_pline_t pline; /* Filter pipeline */ - const H5Z_filter_info_t *filter; /* Pointer to filter information */ - H5P_genplist_t *plist; /* Property list pointer */ - H5Z_filter_t ret_value; /* return value */ - - FUNC_ENTER_API(H5Pget_filter1, H5Z_FILTER_ERROR) - H5TRACE7("Zf", "iIux*zxzx", plist_id, idx, flags, cd_nelmts, cd_values, namelen, - name); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") - - /* Get pipeline info */ - if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") - - /* Check more args */ - if(idx >= pline.nused) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") - - /* Set pointer to particular filter to query */ - filter = &pline.filter[idx]; - - /* Get filter information */ - if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") - - /* Set return value */ - ret_value = filter->id; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter1() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_filter_by_id1 - * - * Purpose: This is an additional query counterpart of H5Pset_filter() and - * returns information about a particular filter in a permanent - * or transient pipeline depending on whether PLIST_ID is a - * dataset creation or transfer property list. On input, - * CD_NELMTS indicates the number of entries in the CD_VALUES - * array allocated by the caller while on exit it contains the - * number of values defined by the filter. The ID - * should be the filter ID to retrieve the parameters for. If the - * filter is not set for the property list, an error will be returned. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, April 5, 2003 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, - size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, - size_t namelen, char name[]/*out*/) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pget_filter_by_id1, FAIL) - H5TRACE7("e", "iZfx*zxzx", plist_id, id, flags, cd_nelmts, cd_values, namelen, - name); - - /* Check args */ - if(cd_nelmts || cd_values) { - /* - * It's likely that users forget to initialize this on input, so - * we'll check that it has a reasonable value. The actual number - * is unimportant because the H5O layer will detect when a message - * is too large. - */ - if(cd_nelmts && *cd_nelmts > 256) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") - if(cd_nelmts && *cd_nelmts > 0 && !cd_values) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") - - /* - * If cd_nelmts is null but cd_values is non-null then just ignore - * cd_values - */ - if(!cd_nelmts) - cd_values = NULL; - } /* end if */ - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get filter info */ - if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_filter_by_id1() */ - -#endif /* H5_NO_DEPRECATED_SYMBOLS */ - diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index a28eeb3..9f144f1 100755 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -52,6 +52,9 @@ #define H5O_CRT_ATTR_MIN_DENSE_SIZE sizeof(unsigned) /* Definitions for object header flags */ #define H5O_CRT_OHDR_FLAGS_SIZE sizeof(uint8_t) +/* Definitions for filter pipeline */ +#define H5O_CRT_PIPELINE_SIZE sizeof(H5O_pline_t) +#define H5O_CRT_PIPELINE_CMP H5P_ocrt_pipeline_cmp /******************/ @@ -70,6 +73,11 @@ /* Property class callbacks */ static herr_t H5P_ocrt_reg_prop(H5P_genclass_t *pclass); +static herr_t H5P_ocrt_copy(hid_t new_plist_t, hid_t old_plist_t, void *copy_data); +static herr_t H5P_ocrt_close(hid_t dxpl_id, void *close_data); + +/* Property callbacks */ +static int H5P_ocrt_pipeline_cmp(const void *value1, const void *value2, size_t size); /*********************/ @@ -85,9 +93,9 @@ const H5P_libclass_t H5P_CLS_OCRT[1] = {{ H5P_ocrt_reg_prop, /* Default property registration routine */ NULL, /* Class creation callback */ NULL, /* Class creation callback info */ - NULL, /* Class copy callback */ + H5P_ocrt_copy, /* Class copy callback */ NULL, /* Class copy callback info */ - NULL, /* Class close callback */ + H5P_ocrt_close, /* Class close callback */ NULL /* Class close callback info */ }}; @@ -121,7 +129,8 @@ H5P_ocrt_reg_prop(H5P_genclass_t *pclass) { unsigned attr_max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF; /* Default max. compact attribute storage settings */ unsigned attr_min_dense = H5O_CRT_ATTR_MIN_DENSE_DEF; /* Default min. dense attribute storage settings */ - uint8_t ohdr_flags = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */ + uint8_t ohdr_flags = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */ + H5O_pline_t pline = H5O_CRT_PIPELINE_DEF; /* Default I/O pipeline setting */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_reg_prop) @@ -141,12 +150,108 @@ H5P_ocrt_reg_prop(H5P_genclass_t *pclass) &ohdr_flags, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the pipeline property */ + if(H5P_register(pclass, H5O_CRT_PIPELINE_NAME, H5O_CRT_PIPELINE_SIZE, + &pline, NULL, NULL, NULL, NULL, NULL, H5O_CRT_PIPELINE_CMP, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_ocrt_reg_prop() */ /*------------------------------------------------------------------------- + * Function: H5P_ocrt_copy + * + * Purpose: Callback routine which is called whenever any object + * creation property list is copied. This routine copies + * the properties from the old list to the new list. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Monday, September 21, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5P_ocrt_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data) +{ + H5O_pline_t src_pline, dst_pline; /* Source & destination pipelines */ + H5P_genplist_t *src_plist; /* Pointer to source property list */ + H5P_genplist_t *dst_plist; /* Pointer to destination property list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_copy) + + /* Verify property list IDs */ + if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list") + if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list") + + /* Get the link pipeline property from the old property list */ + if(H5P_get(src_plist, H5O_CRT_PIPELINE_NAME, &src_pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Make copy of link pipeline */ + if(NULL == H5O_msg_copy(H5O_PLINE_ID, &src_pline, &dst_pline)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't copy link pipeline") + + /* Set the link pipeline property for the destination property list */ + if(H5P_set(dst_plist, H5O_CRT_PIPELINE_NAME, &dst_pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_ocrt_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_ocrt_close + * + * Purpose: Callback routine which is called whenever any object create + * property list is closed. This routine performs any generic + * cleanup needed on the properties the library put into the list. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Monday, September 21, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5P_ocrt_close(hid_t dcpl_id, void UNUSED *close_data) +{ + H5O_pline_t pline; /* I/O pipeline */ + H5P_genplist_t *plist; /* Property list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5P_ocrt_close) + + /* Check arguments */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object creation property list") + + /* Get the link pipeline property from the old property list */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Clean up any values set for the link pipeline */ + if(H5O_msg_reset(H5O_PLINE_ID, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release pipeline info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_ocrt_close() */ + + +/*------------------------------------------------------------------------- * Function: H5Pset_attr_phase_change * * Purpose: Sets the cutoff values for indexes storing attributes @@ -437,3 +542,1043 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_obj_track_times() */ + +/*------------------------------------------------------------------------- + * Function: H5P_modify_filter + * + * Purpose: Modifies the specified FILTER in the + * transient or permanent output filter pipeline + * depending on whether PLIST is a dataset creation or dataset + * transfer property list. The FLAGS argument specifies certain + * general properties of the filter and is documented below. + * The CD_VALUES is an array of CD_NELMTS integers which are + * auxiliary data for the filter. The integer vlues will be + * stored in the dataset object header as part of the filter + * information. + * + * The FLAGS argument is a bit vector of the following fields: + * + * H5Z_FLAG_OPTIONAL(0x0001) + * If this bit is set then the filter is optional. If the + * filter fails during an H5Dwrite() operation then the filter + * is just excluded from the pipeline for the chunk for which it + * failed; the filter will not participate in the pipeline + * during an H5Dread() of the chunk. If this bit is clear and + * the filter fails then the entire I/O operation fails. + * If this bit is set but encoding is disabled for a filter, + * attempting to write will generate an error. + * + * Note: This function currently supports only the permanent filter + * pipeline. That is, PLIST_ID must be a dataset creation + * property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, October 17, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned flags, + size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/]) +{ + H5O_pline_t pline; + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI(H5P_modify_filter, FAIL) + + /* Get the pipeline property to modify */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Modify the filter parameters of the I/O pipeline */ + if(H5Z_modify(&pline, filter, flags, cd_nelmts, cd_values) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_modify_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pmodify_filter + * + * Purpose: Modifies the specified FILTER in the + * transient or permanent output filter pipeline + * depending on whether PLIST is a dataset creation or dataset + * transfer property list. The FLAGS argument specifies certain + * general properties of the filter and is documented below. + * The CD_VALUES is an array of CD_NELMTS integers which are + * auxiliary data for the filter. The integer vlues will be + * stored in the dataset object header as part of the filter + * information. + * + * The FLAGS argument is a bit vector of the following fields: + * + * H5Z_FLAG_OPTIONAL(0x0001) + * If this bit is set then the filter is optional. If the + * filter fails during an H5Dwrite() operation then the filter + * is just excluded from the pipeline for the chunk for which it + * failed; the filter will not participate in the pipeline + * during an H5Dread() of the chunk. If this bit is clear and + * the filter fails then the entire I/O operation fails. + * If this bit is set but encoding is disabled for a filter, + * attempting to write will generate an error. + * + * Note: This function currently supports only the permanent filter + * pipeline. That is, PLIST_ID must be a dataset creation + * property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, April 5, 2003 + * + * Modifications: + * + * Neil Fortner + * Thursday, March 26, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, + size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) +{ + H5P_genplist_t *plist; /* Property list */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pmodify_filter, FAIL) + H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); + + /* Check args */ + if (filter<0 || filter>H5Z_FILTER_MAX) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") + if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") + if (cd_nelmts>0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + + /* Modify the filter parameters of the I/O pipeline */ + if(H5P_modify_filter(plist, filter, flags, cd_nelmts, cd_values) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't modify filter") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pmodify_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_filter + * + * Purpose: Adds the specified FILTER and corresponding properties to the + * end of the data or link output filter pipeline + * depending on whether PLIST is a dataset creation or group + * creation property list. The FLAGS argument specifies certain + * general properties of the filter and is documented below. + * The CD_VALUES is an array of CD_NELMTS integers which are + * auxiliary data for the filter. The integer vlues will be + * stored in the dataset object header as part of the filter + * information. + * + * The FLAGS argument is a bit vector of the following fields: + * + * H5Z_FLAG_OPTIONAL(0x0001) + * If this bit is set then the filter is optional. If the + * filter fails during an H5Dwrite() operation then the filter + * is just excluded from the pipeline for the chunk for which it + * failed; the filter will not participate in the pipeline + * during an H5Dread() of the chunk. If this bit is clear and + * the filter fails then the entire I/O operation fails. + * If this bit is set but encoding is disabled for a filter, + * attempting to write will generate an error. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + * Modifications: + * + * Raymond Lu + * Tuesday, October 2, 2001 + * Changed the way to check parameter and set property for + * generic property list. + * + * Neil Fortner + * Wednesday, May 20, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, + size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_filter, FAIL) + H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values); + + /* Check args */ + if (filter<0 || filter>H5Z_FILTER_MAX) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier") + if (flags & ~((unsigned)H5Z_FLAG_DEFMASK)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") + if (cd_nelmts>0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to append to */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Add the filter to the I/O pipeline */ + if(H5Z_append(&pline, filter, flags, cd_nelmts, cd_values) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_nfilters + * + * Purpose: Returns the number of filters in the data or link + * pipeline depending on whether PLIST_ID is a dataset creation + * or group creation property list. In each pipeline the + * filters are numbered from zero through N-1 where N is the + * value returned by this function. During output to the file + * the filters of a pipeline are applied in increasing order + * (the inverse is true for input). + * + * Return: Success: Number of filters or zero if there are none. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Tuesday, August 4, 1998 + * + * Modifications: + * + * Neil Fortner + * Wednesday, May 20, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +int +H5Pget_nfilters(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + int ret_value; /* return value */ + + FUNC_ENTER_API(H5Pget_nfilters, FAIL) + H5TRACE1("Is", "i", plist_id); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Set return value */ + ret_value=(int)(pline.nused); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_nfilters */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter2 + * + * Purpose: This is the query counterpart of H5Pset_filter() and returns + * information about a particular filter number in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. FILTER_CONFIG is a bit + * field contaning encode/decode flags from H5Zpublic.h. The IDX + * should be a value between zero and N-1 as described for + * H5Pget_nfilters() and the function will return failure if the + * filter number is out of range. + * + * Return: Success: Filter identification number. + * + * Failure: H5Z_FILTER_ERROR (Negative) + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + * Modifications: + * + * Neil Fortner + * Wednesday, May 20, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +H5Z_filter_t +H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, + unsigned *filter_config /*out*/) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + const H5Z_filter_info_t *filter; /* Pointer to filter information */ + H5Z_filter_t ret_value; /* return value */ + + FUNC_ENTER_API(H5Pget_filter2, H5Z_FILTER_ERROR) + H5TRACE8("Zf", "iIux*zxzxx", plist_id, idx, flags, cd_nelmts, cd_values, + namelen, name, filter_config); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") + + /* Check index */ + if(idx >= pline.nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") + + /* Set pointer to particular filter to query */ + filter = &pline.filter[idx]; + + /* Get filter information */ + if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") + + /* Set return value */ + ret_value = filter->id; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter2() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_get_filter_by_id + * + * Purpose: This is an additional query counterpart of H5Pset_filter() and + * returns information about a particular filter in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. FILTER_CONFIG is a bit + * field contaning encode/decode flags from H5Zpublic.h. The ID + * should be the filter ID to retrieve the parameters for. If the + * filter is not set for the property list, an error will be returned. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Wednesday, October 17, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, unsigned *filter_config) +{ + H5O_pline_t pline; /* Filter pipeline */ + H5Z_filter_info_t *filter; /* Pointer to filter information */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5P_get_filter_by_id, FAIL) + + /* Get pipeline info */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Get pointer to filter in pipeline */ + if(NULL == (filter = H5Z_filter_info(&pline, id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid") + + /* Get filter information */ + if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, filter_config) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_get_filter_by_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter_by_id2 + * + * Purpose: This is an additional query counterpart of H5Pset_filter() and + * returns information about a particular filter in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. FILTER_CONFIG is a bit + * field contaning encode/decode flags from H5Zpublic.h. The ID + * should be the filter ID to retrieve the parameters for. If the + * filter is not set for the property list, an error will be returned. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, April 5, 2003 + * + * Modifications: + * + * Neil Fortner + * Thursday, May 21, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, unsigned *filter_config) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + const H5Z_filter_info_t *filter; /* Pointer to filter information */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pget_filter_by_id2, FAIL) + H5TRACE8("e", "iZfx*zxzx*Iu", plist_id, id, flags, cd_nelmts, cd_values, + namelen, name, filter_config); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Get pointer to filter in pipeline */ + if(NULL == (filter = H5Z_filter_info(&pline, id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID is invalid") + + /* Get filter information */ + if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, + name, filter_config) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter_by_id2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pall_filters_avail + * + * Purpose: This is a query routine to verify that all the filters set + * in the dataset creation property list are available currently. + * + * Return: Success: TRUE if all filters available, FALSE if one or + * more filters not currently available. + * Failure: FAIL on error + * + * Programmer: Quincey Koziol + * Tuesday, April 8, 2003 + * + * Modifications: + * + * Neil Fortner + * Thursday, May 21, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +htri_t +H5Pall_filters_avail(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Pall_filters_avail, FAIL) + H5TRACE1("t", "i", plist_id); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to query */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Check if all filters are available */ + if((ret_value = H5Z_all_filters_avail(&pline)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't check pipeline information") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pall_filters_avail() */ + + +/*------------------------------------------------------------------------- + * Function: H5Premove_filter + * + * Purpose: Deletes a filter from the dataset creation property list; + * deletes all filters if FILTER is H5Z_FILTER_NONE + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Pedro Vicente + * January 26, 2004 + * + * Modifications: + * + * Neil Fortner + * Thursday, May 21, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Premove_filter(hid_t plist_id, H5Z_filter_t filter) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Premove_filter, FAIL) + H5TRACE2("e", "iZf", plist_id, filter); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to modify */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Check if there are any filters */ + if (pline.filter) { + /* Delete filter */ + if(H5Z_delete(&pline, filter) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't delete filter") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Premove_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_deflate + * + * Purpose: Sets the compression method for a dataset or group link + * filter pipeline (depending on whether PLIST_ID is a dataset + * creation or group creation property list) to H5Z_FILTER_DEFLATE + * and the compression level to LEVEL which should be a value + * between zero and nine, inclusive. Lower compression levels + * are faster but result in less compression. This is the same + * algorithm as used by the GNU gzip program. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + * Modifications: + * + * Raymond Lu + * Tuesday, October 2, 2001 + * Changed the way to check parameter and set property for + * generic property list. + * + * Neil Fortner + * Thursday, March 26, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_deflate(hid_t plist_id, unsigned level) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_deflate, FAIL) + H5TRACE2("e", "iIu", plist_id, level); + + /* Check arguments */ + if(level > 9) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to append to */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Add the filter */ + if(H5Z_append(&pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &level) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_deflate() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fletcher32 + * + * Purpose: Sets Fletcher32 checksum of EDC for a dataset creation + * property list or group creation property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Dec 19, 2002 + * + * Modifications: + * + * Neil Fortner + * Wednesday, May 6, 2009 + * Overloaded to accept gcpl's as well as dcpl's and moved to + * H5Pocpl.c + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fletcher32(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list */ + H5O_pline_t pline; /* Filter pipeline */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_fletcher32, FAIL) + H5TRACE1("e", "i", plist_id); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the pipeline property to append to */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline") + + /* Add the Fletcher32 checksum as a filter */ + if(H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline") + + /* Put the I/O pipeline information back into the property list */ + if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_fletcher32() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_get_filter + * + * Purpose: Internal component of H5Pget_filter & H5Pget_filter_id + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, October 23, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_get_filter(const H5Z_filter_info_t *filter, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/, + unsigned *filter_config /*out*/) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5P_get_filter) + + /* Check arguments */ + HDassert(filter); + + /* Filter flags */ + if(flags) + *flags = filter->flags; + + /* Filter parameters */ + if(cd_values) { + size_t i; /* Local index variable */ + + for(i = 0; i < filter->cd_nelmts && i < *cd_nelmts; i++) + cd_values[i] = filter->cd_values[i]; + } /* end if */ + + /* Number of filter parameters */ + if(cd_nelmts) + *cd_nelmts = filter->cd_nelmts; + + /* Filter name */ + if(namelen > 0 && name) { + const char *s = filter->name; + + /* If there's no name on the filter, use the class's filter name */ + if(!s) { + H5Z_class2_t *cls = H5Z_find(filter->id); + + if(cls) + s = cls->name; + } /* end if */ + + /* Check for actual name */ + if(s) { + HDstrncpy(name, s, namelen); + name[namelen - 1] = '\0'; + } /* end if */ + else { + /* Check for unknown library filter */ + /* (probably from a future version of the library) */ + if(filter->id < 256) { + HDstrncpy(name, "Unknown library filter", namelen); + name[namelen - 1] = '\0'; + } /* end if */ + else + name[0] = '\0'; + } /* end if */ + } /* end if */ + + /* Filter configuration (assume filter ID has already been checked) */ + if(filter_config) + H5Zget_filter_info(filter->id, filter_config); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P_get_filter() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_ocrt_pipeline_cmp + * + * Purpose: Callback routine which is called whenever a filter pipeline + * property in a 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 + * + *------------------------------------------------------------------------- + */ +int +H5P_ocrt_pipeline_cmp(const void *_pline1, const void *_pline2, size_t UNUSED size) +{ + const H5O_pline_t *pline1 = (const H5O_pline_t *)_pline1, /* Create local aliases for values */ + *pline2 = (const H5O_pline_t *)_pline2; + int cmp_value; /* Value from comparison */ + herr_t ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI_NOFUNC(H5P_ocrt_pipeline_cmp) + + /* Sanity check */ + HDassert(pline1); + HDassert(pline2); + HDassert(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->nused < pline2->nused) HGOTO_DONE(-1); + if(pline1->nused > pline2->nused) 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->nused > 0) { + size_t u; /* Local index variable */ + + /* Loop through all filters, comparing them */ + for(u = 0; u < pline1->nused; u++) { + /* Check the ID of the filter */ + if(pline1->filter[u].id < pline2->filter[u].id) HGOTO_DONE(-1); + if(pline1->filter[u].id > pline2->filter[u].id) HGOTO_DONE(1); + + /* Check the flags for the filter */ + if(pline1->filter[u].flags < pline2->filter[u].flags) HGOTO_DONE(-1); + if(pline1->filter[u].flags > pline2->filter[u].flags) HGOTO_DONE(1); + + /* Check the name of the filter */ + if(pline1->filter[u].name == NULL && pline2->filter[u].name != NULL) HGOTO_DONE(-1); + if(pline1->filter[u].name != NULL && pline2->filter[u].name == NULL) HGOTO_DONE(1); + if(pline1->filter[u].name != NULL) + if((cmp_value = HDstrcmp(pline1->filter[u].name, pline2->filter[u].name)) != 0) + HGOTO_DONE(cmp_value); + + /* Check the number of parameters for the filter */ + if(pline1->filter[u].cd_nelmts < pline2->filter[u].cd_nelmts) HGOTO_DONE(-1); + if(pline1->filter[u].cd_nelmts > pline2->filter[u].cd_nelmts) HGOTO_DONE(1); + + /* Check the filter parameter information */ + if(pline1->filter[u].cd_values == NULL && pline2->filter[u].cd_values != NULL) HGOTO_DONE(-1); + if(pline1->filter[u].cd_values != NULL && pline2->filter[u].cd_values == NULL) HGOTO_DONE(1); + if(pline1->filter[u].cd_values != NULL && pline1->filter[u].cd_nelmts > 0) { + size_t v; /* Local index variable */ + + /* Loop through all parameters, comparing them */ + for(v = 0; v < pline1->filter[u].cd_nelmts; v++) { + /* Check each parameter for the filter */ + if(pline1->filter[u].cd_values[v] < pline2->filter[u].cd_values[v]) HGOTO_DONE(-1); + if(pline1->filter[u].cd_values[v] > pline2->filter[u].cd_values[v]) HGOTO_DONE(1); + } /* end for */ + } /* end if */ + } /* end for */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_ocrt_pipeline_cmp() */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter1 + * + * Purpose: This is the query counterpart of H5Pset_filter() and returns + * information about a particular filter number in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. The IDX + * should be a value between zero and N-1 as described for + * H5Pget_nfilters() and the function will return failure if the + * filter number is out of range. + * + * Return: Success: Filter identification number. + * + * Failure: H5Z_FILTER_ERROR (Negative) + * + * Programmer: Robb Matzke + * Wednesday, April 15, 1998 + * + *------------------------------------------------------------------------- + */ +H5Z_filter_t +H5Pget_filter1(hid_t plist_id, unsigned idx, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/) +{ + H5O_pline_t pline; /* Filter pipeline */ + const H5Z_filter_info_t *filter; /* Pointer to filter information */ + H5P_genplist_t *plist; /* Property list pointer */ + H5Z_filter_t ret_value; /* return value */ + + FUNC_ENTER_API(H5Pget_filter1, H5Z_FILTER_ERROR) + H5TRACE7("Zf", "iIux*zxzx", plist_id, idx, flags, cd_nelmts, cd_values, namelen, + name); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5Z_FILTER_ERROR, "can't find object for ID") + + /* Get pipeline info */ + if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get pipeline") + + /* Check more args */ + if(idx >= pline.nused) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid") + + /* Set pointer to particular filter to query */ + filter = &pline.filter[idx]; + + /* Get filter information */ + if(H5P_get_filter(filter, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5Z_FILTER_ERROR, "can't get filter info") + + /* Set return value */ + ret_value = filter->id; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter1() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_filter_by_id1 + * + * Purpose: This is an additional query counterpart of H5Pset_filter() and + * returns information about a particular filter in a permanent + * or transient pipeline depending on whether PLIST_ID is a + * dataset creation or transfer property list. On input, + * CD_NELMTS indicates the number of entries in the CD_VALUES + * array allocated by the caller while on exit it contains the + * number of values defined by the filter. The ID + * should be the filter ID to retrieve the parameters for. If the + * filter is not set for the property list, an error will be returned. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, April 5, 2003 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/, + size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, + size_t namelen, char name[]/*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pget_filter_by_id1, FAIL) + H5TRACE7("e", "iZfx*zxzx", plist_id, id, flags, cd_nelmts, cd_values, namelen, + name); + + /* Check args */ + if(cd_nelmts || cd_values) { + /* + * It's likely that users forget to initialize this on input, so + * we'll check that it has a reasonable value. The actual number + * is unimportant because the H5O layer will detect when a message + * is too large. + */ + if(cd_nelmts && *cd_nelmts > 256) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "probable uninitialized *cd_nelmts argument") + if(cd_nelmts && *cd_nelmts > 0 && !cd_values) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "client data values not supplied") + + /* + * If cd_nelmts is null but cd_values is non-null then just ignore + * cd_values + */ + if(!cd_nelmts) + cd_values = NULL; + } /* end if */ + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get filter info */ + if(H5P_get_filter_by_id(plist, id, flags, cd_nelmts, cd_values, namelen, name, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get filter info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_filter_by_id1() */ + +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index 2959ddc..fd9c65a 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -178,6 +178,9 @@ H5_DLL char *H5P_get_class_path(H5P_genclass_t *pclass); H5_DLL H5P_genclass_t *H5P_open_class_path(const char *path); H5_DLL H5P_genclass_t *H5P_get_class_parent(const H5P_genclass_t *pclass); H5_DLL herr_t H5P_close_class(void *_pclass); +H5_DLL herr_t H5P_get_filter(const H5Z_filter_info_t *filter, + unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[], + size_t namelen, char name[], unsigned *filter_config); /* Testing functions */ #ifdef H5P_TESTING diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 885249d..0b37938 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -86,6 +86,11 @@ H5_DLL herr_t H5P_is_fill_value_defined(const H5O_fill_t *fill, H5D_fill_value_t *status); H5_DLL int H5P_fill_value_cmp(const void *value1, const void *value2, size_t size); +H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, + unsigned flags, size_t cd_nelmts, const unsigned cd_values[]); +H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, + unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[], + size_t namelen, char name[], unsigned *filter_config); /* *SPECIAL* Don't make more of these! -QAK */ H5_DLL htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id); @@ -98,12 +103,6 @@ H5_DLL void *H5P_peek_voidp(H5P_genplist_t *plist, const char *name); H5_DLL size_t H5P_peek_size_t(H5P_genplist_t *plist, const char *name); /* Private DCPL routines */ -H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter, - unsigned flags, size_t cd_nelmts, const unsigned cd_values[/*cd_nelmts*/]); -H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id, - unsigned int *flags/*out*/, size_t *cd_nelmts/*in_out*/, - unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/, - unsigned *filter_config); H5_DLL herr_t H5P_fill_value_defined(H5P_genplist_t *plist, H5D_fill_value_t *status); H5_DLL herr_t H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type, diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 1e4cf2f..1c0bb61 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -206,6 +206,27 @@ H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flag H5_DLL herr_t H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags); H5_DLL herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times); H5_DLL herr_t H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times); +H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, + unsigned int flags, size_t cd_nelmts, + const unsigned int cd_values[/*cd_nelmts*/]); +H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, + unsigned int flags, size_t cd_nelmts, + const unsigned int c_values[]); +H5_DLL int H5Pget_nfilters(hid_t plist_id); +H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter, + unsigned int *flags/*out*/, + size_t *cd_nelmts/*out*/, + unsigned cd_values[]/*out*/, + size_t namelen, char name[], + unsigned *filter_config /*out*/); +H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, + unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/, + unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/, + unsigned *filter_config/*out*/); +H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id); +H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter); +H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression); +H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id); /* File creation property list (FCPL) routines */ H5_DLL herr_t H5Pset_userblock(hid_t plist_id, hsize_t size); @@ -278,31 +299,10 @@ H5_DLL int H5Pget_external_count(hid_t plist_id); H5_DLL herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name/*out*/, off_t *offset/*out*/, hsize_t *size/*out*/); -H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, - unsigned int flags, size_t cd_nelmts, - const unsigned int cd_values[/*cd_nelmts*/]); -H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, - unsigned int flags, size_t cd_nelmts, - const unsigned int c_values[]); -H5_DLL int H5Pget_nfilters(hid_t plist_id); -H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter, - unsigned int *flags/*out*/, - size_t *cd_nelmts/*out*/, - unsigned cd_values[]/*out*/, - size_t namelen, char name[], - unsigned *filter_config /*out*/); -H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, - unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/, - unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/, - unsigned *filter_config/*out*/); -H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id); -H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter); -H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression); H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block); H5_DLL herr_t H5Pset_shuffle(hid_t plist_id); H5_DLL herr_t H5Pset_nbit(hid_t plist_id); H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor); -H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id); H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value); H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, diff --git a/src/H5Z.c b/src/H5Z.c index dc1ad80..c295df3 100644 --- a/src/H5Z.c +++ b/src/H5Z.c @@ -490,17 +490,103 @@ done: * of passing in the dataset's dataspace, since the chunk * dimensions are what the I/O filter will actually see * - * Modifications: + *------------------------------------------------------------------------- + */ +static herr_t +H5Z_prelude_callback(const H5O_pline_t *pline, hid_t dcpl_id, hid_t type_id, + hid_t space_id, H5Z_prelude_type_t prelude_type) +{ + H5Z_class2_t *fclass; /* Individual filter information */ + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5Z_prelude_callback) + + HDassert(pline->nused > 0); + + /* Iterate over filters */ + for(u = 0; u < pline->nused; u++) { + /* Get filter information */ + if(NULL == (fclass = H5Z_find(pline->filter[u].id))) { + /* Ignore errors from optional filters */ + if(pline->filter[u].flags & H5Z_FLAG_OPTIONAL) + H5E_clear_stack(NULL); + else + HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located") + } /* end if */ + else { + /* Make correct callback */ + switch(prelude_type) { + case H5Z_PRELUDE_CAN_APPLY: + /* Check if filter is configured to be able to encode */ + if(!fclass->encoder_present) + HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled."); + + + /* Check if there is a "can apply" callback */ + if(fclass->can_apply) { + /* Make callback to filter's "can apply" function */ + herr_t status = (fclass->can_apply)(dcpl_id, type_id, space_id); + + /* Check return value */ + if(status <= 0) { + /* Indicate filter can't apply to this combination of parameters */ + if(status == 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate") + /* Indicate error during filter callback */ + else + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback") + } /* end if */ + } /* end if */ + break; + + case H5Z_PRELUDE_SET_LOCAL: + /* Check if there is a "set local" callback */ + if(fclass->set_local) { + /* Make callback to filter's "set local" function */ + if((fclass->set_local)(dcpl_id, type_id, space_id) < 0) + /* Indicate error during filter callback */ + HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback") + } /* end if */ + break; + + default: + HDassert("invalid prelude type" && 0); + } /* end switch */ + } /* end else */ + } /* end for */ + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_prelude_callback() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_prepare_prelude_callback_dcpl + * + * Purpose: Prepares to make a dataset creation "prelude" callback + * for the "can_apply" or "set_local" routines. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Friday, April 4, 2003 + * + * Notes: + * The chunk dimensions are used to create a dataspace, instead + * of passing in the dataset's dataspace, since the chunk + * dimensions are what the I/O filter will actually see * *------------------------------------------------------------------------- */ static herr_t -H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type) +H5Z_prepare_prelude_callback_dcpl(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type) { hid_t space_id = -1; /* ID for dataspace describing chunk */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5Z_prelude_callback) + FUNC_ENTER_NOAPI_NOINIT(H5Z_prepare_prelude_callback_dcpl) HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id)); HDassert(H5I_DATATYPE == H5I_get_type(type_id)); @@ -520,10 +606,10 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty /* Check if the dataset is chunked */ if(H5D_CHUNKED == dcpl_layout.type) { - H5O_pline_t dcpl_pline; /* Dataset's I/O pipeline information */ + H5O_pline_t dcpl_pline; /* Object's I/O pipeline information */ /* Get I/O pipeline information */ - if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0) + if(H5P_get(dc_plist, H5O_CRT_PIPELINE_NAME, &dcpl_pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter") /* Check if the chunks have filters */ @@ -544,59 +630,9 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") } /* end if */ - /* Iterate over filters */ - for(u = 0; u < dcpl_pline.nused; u++) { - H5Z_class2_t *fclass; /* Individual filter information */ - - /* Get filter information */ - if(NULL == (fclass = H5Z_find(dcpl_pline.filter[u].id))) { - /* Ignore errors from optional filters */ - if(dcpl_pline.filter[u].flags & H5Z_FLAG_OPTIONAL) - H5E_clear_stack(NULL); - else - HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located") - } /* end if */ - else { - /* Make correct callback */ - switch(prelude_type) { - case H5Z_PRELUDE_CAN_APPLY: - /* Check if filter is configured to be able to encode */ - if(!fclass->encoder_present) - HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled."); - - - /* Check if there is a "can apply" callback */ - if(fclass->can_apply) { - /* Make callback to filter's "can apply" function */ - herr_t status = (fclass->can_apply)(dcpl_id, type_id, space_id); - - /* Check return value */ - if(status <= 0) { - /* Indicate filter can't apply to this combination of parameters */ - if(status == 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate") - /* Indicate error during filter callback */ - else - HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback") - } /* end if */ - } /* end if */ - break; - - case H5Z_PRELUDE_SET_LOCAL: - /* Check if there is a "set local" callback */ - if(fclass->set_local) { - /* Make callback to filter's "set local" function */ - if((fclass->set_local)(dcpl_id, type_id, space_id) < 0) - /* Indicate error during filter callback */ - HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback") - } /* end if */ - break; - - default: - HDassert("invalid prelude type" && 0); - } /* end switch */ - } /* end else */ - } /* end for */ + /* Make the callbacks */ + if(H5Z_prelude_callback(&dcpl_pline, dcpl_id, type_id, space_id, prelude_type) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter") } /* end if */ } /* end if */ } /* end if */ @@ -606,7 +642,7 @@ done: HDONE_ERROR(H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5Z_prelude_callback() */ +} /* end H5Z_prepare_prelude_callback_dcpl() */ /*------------------------------------------------------------------------- @@ -635,11 +671,8 @@ H5Z_can_apply(hid_t dcpl_id, hid_t type_id) FUNC_ENTER_NOAPI(H5Z_can_apply, FAIL) - HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id)); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); - /* Make "can apply" callbacks for filters in pipeline */ - if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY) < 0) + if(H5Z_prepare_prelude_callback_dcpl(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY) < 0) HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter") done: @@ -673,11 +706,8 @@ H5Z_set_local(hid_t dcpl_id, hid_t type_id) FUNC_ENTER_NOAPI(H5Z_set_local, FAIL) - HDassert(H5I_GENPROP_LST == H5I_get_type(dcpl_id)); - HDassert(H5I_DATATYPE == H5I_get_type(type_id)); - /* Make "set local" callbacks for filters in pipeline */ - if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL) < 0) + if(H5Z_prepare_prelude_callback_dcpl(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL) < 0) HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set") done: @@ -686,6 +716,75 @@ done: /*------------------------------------------------------------------------- + * Function: H5Z_can_apply_direct + * + * Purpose: Checks if all the filters defined in the pipeline can be + * applied to an opaque byte stream (currently only a group). + * The pipeline is assumed to have at least one filter. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Tuesday, September 22, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Z_can_apply_direct(const H5O_pline_t *pline) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_can_apply_direct, FAIL) + + HDassert(pline->nused > 0); + + /* Make "can apply" callbacks for filters in pipeline */ + if(H5Z_prelude_callback(pline, -1, -1, -1, H5Z_PRELUDE_CAN_APPLY) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_can_apply_direct() */ + + +/*------------------------------------------------------------------------- + * Function: H5Z_set_local_direct + * + * Purpose: Makes callbacks to modify local settings for filters on a + * new opaque object. The pipeline is assumed to have at + * least one filter. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Tuesday, September 22, 2009 + * + * Notes: + * This callback will almost certainly not do anything + * useful, other than to make certain that the filter will + * accept opque data. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Z_set_local_direct(const H5O_pline_t *pline) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5Z_set_local_direct, FAIL) + + HDassert(pline->nused > 0); + + /* Make "set local" callbacks for filters in pipeline */ + if(H5Z_prelude_callback(pline, -1, -1, -1, H5Z_PRELUDE_SET_LOCAL) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Z_set_local_direct() */ + + +/*------------------------------------------------------------------------- * Function: H5Z_modify * * Purpose: Modify filter parameters for specified pipeline. @@ -1286,33 +1385,3 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Zget_filter_info() */ - -/*------------------------------------------------------------------------- - * Function: H5Z_set_latest_version - * - * Purpose: Set the encoding for a I/O filter pipeline to the latest version. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, July 24, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Z_set_latest_version(H5O_pline_t *pline) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5Z_set_latest_version, FAIL) - - /* Sanity check */ - HDassert(pline); - - /* Set encoding of I/O pipeline to latest version */ - pline->version = H5O_PLINE_VERSION_LATEST; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5Z_set_latest_version() */ - diff --git a/src/H5Zpkg.h b/src/H5Zpkg.h index ae33def..959ec28 100644 --- a/src/H5Zpkg.h +++ b/src/H5Zpkg.h @@ -24,20 +24,6 @@ #include "H5Zprivate.h" /* Filter functions */ -/* The initial version of the format */ -#define H5O_PLINE_VERSION_1 1 - -/* This version encodes the message fields more efficiently */ -/* (Drops the reserved bytes, doesn't align the name and doesn't encode the - * filter name at all if it's a filter provided by the library) - */ -#define H5O_PLINE_VERSION_2 2 - -/* The latest version of the format. Look through the 'encode' and 'size' - * callbacks for places to change when updating this. */ -#define H5O_PLINE_VERSION_LATEST H5O_PLINE_VERSION_2 - - #ifdef H5_HAVE_FILTER_DEFLATE /* * Deflate filter diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h index 3ce0a0c..c2d6f7e 100644 --- a/src/H5Zprivate.h +++ b/src/H5Zprivate.h @@ -87,11 +87,12 @@ H5_DLL herr_t H5Z_pipeline(const struct H5O_pline_t *pline, H5_DLL H5Z_class2_t *H5Z_find(H5Z_filter_t id); H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id); H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id); +H5_DLL herr_t H5Z_can_apply_direct(const struct H5O_pline_t *pline); +H5_DLL herr_t H5Z_set_local_direct(const struct H5O_pline_t *pline); H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline, H5Z_filter_t filter); H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline); H5_DLL herr_t H5Z_delete(struct H5O_pline_t *pline, H5Z_filter_t filter); -H5_DLL herr_t H5Z_set_latest_version(struct H5O_pline_t *pline); /* Data Transform Functions */ typedef struct H5Z_data_xform_t H5Z_data_xform_t; /* Defined in H5Ztrans.c */ diff --git a/src/H5private.h b/src/H5private.h index 2c4576f..035f6db 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -460,6 +460,11 @@ typedef enum { H5_COPY_DEEP /* Deep copy from source to destination, including duplicating fields pointed to */ } H5_copy_depth_t; +/* Common object copying udata (right now only used for groups and datasets) */ +typedef struct H5O_copy_file_ud_common_t { + struct H5O_pline_t *src_pline; /* Copy of filter pipeline for object */ +} H5O_copy_file_ud_common_t; + /* Unique object "position" */ typedef struct { unsigned long fileno; /* The unique identifier for the file of the object */ diff --git a/test/fheap.c b/test/fheap.c index f45f856..26bcaec 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -2769,8 +2769,6 @@ test_filtered_create(hid_t fapl, H5HF_create_t *cparam) if(!H5F_addr_defined(fh_addr)) TEST_ERROR -/* XXX: Check heap's I/O filter settings? */ - /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) FAIL_STACK_ERROR @@ -2799,8 +2797,6 @@ test_filtered_create(hid_t fapl, H5HF_create_t *cparam) if(H5HF_cmp_cparam_test(&tmp_cparam, &test_cparam)) FAIL_STACK_ERROR -/* XXX: Check heap's I/O filter settings? */ - /* Close the fractal heap */ if(H5HF_close(fh, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR diff --git a/test/links.c b/test/links.c index 3619c27..8ee16a6 100644 --- a/test/links.c +++ b/test/links.c @@ -176,6 +176,8 @@ const char *FILENAME[] = { #define H5L_DIM1 100 #define H5L_DIM2 100 +#define FILTER_FILESIZE_MAX_FRACTION .9 + /* Creation order macros */ #define CORDER_GROUP_NAME "corder_group" #define CORDER_SOFT_GROUP_NAME "corder_soft_group" @@ -8520,6 +8522,386 @@ error: /*------------------------------------------------------------------------- + * Function: link_filters + * + * Purpose: Tests adding filters to group link storage. Also tests + * copying these groups. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Tuesday, June 16, 2009 + * + *------------------------------------------------------------------------- + */ +static enum { + LFS_INIT, + LFS_CAN_APPLY_CALLED, + LFS_SET_LOCAL_CALLED, + LFS_ENCODED, + LFS_DECODED +} link_filter_state; + +static herr_t link_filter_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id) +{ + if(dcpl_id >= 0 || type_id >= 0 || space_id >= 0) + return -1; + + if(link_filter_state >= LFS_ENCODED) + return 1; + + if(link_filter_state != LFS_INIT) + return -1; + + link_filter_state = LFS_CAN_APPLY_CALLED; + + return 1; +} /* end link_fitler_can_apply */ + +static herr_t link_filter_set_local(hid_t dcpl_id, hid_t type_id, hid_t space_id) +{ + if(dcpl_id >= 0 || type_id >= 0 || space_id >= 0) + return -1; + + if(link_filter_state >= LFS_ENCODED) + return 0; + + if(link_filter_state != LFS_CAN_APPLY_CALLED) + return -1; + + link_filter_state = LFS_SET_LOCAL_CALLED; + + return 0; +} /* end link_filter_set_local */ + +static size_t link_filter_filter(unsigned int flags, size_t cd_nelmts, + const unsigned int cd_values[], size_t nbytes, size_t UNUSED *buf_size, + void UNUSED **buf) +{ + if(flags & H5Z_FLAG_OPTIONAL || cd_nelmts != 1 || cd_values[0] != 2112) + return 0; + + if(link_filter_state == LFS_DECODED) + return nbytes; + + if(flags & H5Z_FLAG_REVERSE) { + if(link_filter_state != LFS_ENCODED) + return 0; + link_filter_state = LFS_DECODED; + } else { + if(link_filter_state < LFS_SET_LOCAL_CALLED) + return 0; + link_filter_state = LFS_ENCODED; + } /* end else */ + + return nbytes; +} /* end link_filter_filter */ + +static int +link_filters(hid_t fapl, hbool_t new_format) +{ + hid_t fid = -1, fcpl = -1; + hid_t gid1 = -1, gid2 = -1, gcpl1 = -1, gcpl2 = -1; + hid_t lcpl = -1; + size_t cd_nelmts = 1; + unsigned cd_value = 2112; + unsigned cd_value_out; + unsigned flags_out; + unsigned filter_config_out; + int nfilters = 0; + H5Z_class2_t filter_class; + char name_out[24]; + char filename[NAME_BUF_SIZE]; + htri_t tri_ret; + herr_t status; + + /* This test actually always uses the new group format for the main group. + * The new format flag affects the version of object header messages, + * etc., which are important for this test. */ + if(new_format) + TESTING("group link filters (w/new group format)") + else + TESTING("group link filters") + + /* Initialize link filter state global */ + link_filter_state = LFS_INIT; + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create gcpl, force use of dense storage */ + if((gcpl1 = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + if(H5Pset_link_phase_change(gcpl1, 2, 2) < 0) TEST_ERROR + + /* Add deflate and checksum filters, if available */ + if((tri_ret = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0) TEST_ERROR + if(tri_ret) { + if(H5Pset_deflate(gcpl1, 6) < 0) TEST_ERROR + nfilters++; + } /* end if */ + if((tri_ret = H5Zfilter_avail(H5Z_FILTER_FLETCHER32)) < 0) TEST_ERROR + if(tri_ret) { + if(H5Pset_fletcher32(gcpl1) < 0) TEST_ERROR + nfilters++; + } /* end if */ + + /* Register and add custom filter */ + filter_class.version = H5Z_CLASS_T_VERS; + filter_class.id = H5Z_FILTER_RESERVED + 42; + filter_class.encoder_present = TRUE; + filter_class.decoder_present = TRUE; + filter_class.name = "custom_link_filter"; + filter_class.can_apply = link_filter_can_apply; + filter_class.set_local = link_filter_set_local; + filter_class.filter = link_filter_filter; + if(H5Zregister(&filter_class) < 0) TEST_ERROR + if(H5Pset_filter(gcpl1, H5Z_FILTER_RESERVED + 42, 0, (size_t)1, &cd_value) < 0) + TEST_ERROR + nfilters++; + + /* Test various other filter functions for use on gcpl's */ + if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR + if(H5Pall_filters_avail(gcpl1) != TRUE) TEST_ERROR + + /* Create a group using this filter, add some soft links to it */ + if((gid1 = H5Gcreate2(fid, "group1", H5P_DEFAULT, gcpl1, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file and group */ + if(H5Gclose(gid1) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Verify the filter has been applied */ + if(link_filter_state != LFS_ENCODED) TEST_ERROR + + /* Reopen file and group */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + if((gid1 = H5Gopen2(fid, "group1", H5P_DEFAULT)) < 0) TEST_ERROR + + /* Retrieve gcpl, verify number of filters */ + if((gcpl2 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR + if(H5Pclose(gcpl2) < 0) TEST_ERROR + + /* Now try copying gcpl1, and verify number of filters */ + if((gcpl2 = H5Pcopy(gcpl1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR + if(H5Pclose(gcpl2) < 0) TEST_ERROR + + /* Add another soft link */ + if(H5Lcreate_soft("/", gid1, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Copy the group */ + if(H5Ocopy(fid, "group1", fid, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if((gid2 = H5Gopen2(fid, "group2", H5P_DEFAULT)) <0) TEST_ERROR + + /* Verify that all links have been copied */ + if(H5Lexists(gid2, "link1", H5P_DEFAULT) != TRUE) TEST_ERROR + if(H5Lexists(gid2, "link2", H5P_DEFAULT) != TRUE) TEST_ERROR + if(H5Lexists(gid2, "link3", H5P_DEFAULT) != TRUE) TEST_ERROR + if(H5Lexists(gid2, "link4", H5P_DEFAULT) != TRUE) TEST_ERROR + + /* Retrieve gcpl, verify number of filters */ + if((gcpl2 = H5Gget_create_plist(gid2)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR + + /* Delete 3 links to force the group back into compact mode */ + if(H5Ldelete(gid1, "link2", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(gid1, "link3", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(gid1, "link4", H5P_DEFAULT) < 0) TEST_ERROR + + /* Close file and groups */ + if(H5Gclose(gid1) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Reset link filter state */ + link_filter_state = LFS_INIT; + + /* Reopen file and group, add 2 links */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + if((gid1 = H5Gopen2(fid, "group1", H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file and group */ + if(H5Gclose(gid1) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Verify that the filter was reapplied */ + if(link_filter_state != LFS_ENCODED) TEST_ERROR + + /* Test H5Pget_filter_by_id2 and H5Pget_filter2 */ + if(H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, &flags_out, + &cd_nelmts, &cd_value_out, (size_t)24, name_out, &filter_config_out) < 0) + TEST_ERROR + if(flags_out != 0 || cd_value_out != cd_value + || HDstrcmp(filter_class.name, name_out) + || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED + | H5Z_FILTER_CONFIG_DECODE_ENABLED)) + TEST_ERROR + if(H5Pget_filter2(gcpl2, 2, &flags_out, &cd_nelmts, &cd_value_out, (size_t)24, + name_out, &filter_config_out) < 0) + TEST_ERROR + if(flags_out != 0 || cd_value_out != cd_value + || HDstrcmp(filter_class.name, name_out) + || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED + | H5Z_FILTER_CONFIG_DECODE_ENABLED)) + TEST_ERROR + + /* Test H5Pmodify_filter */ + cd_value++; + if(H5Pmodify_filter(gcpl2, H5Z_FILTER_RESERVED + 42, 0, (size_t)1, &cd_value) < 0) + TEST_ERROR + if(H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, &flags_out, + &cd_nelmts, &cd_value_out, (size_t)24, name_out, &filter_config_out) < 0) + TEST_ERROR + if(flags_out != 0 || cd_value_out != cd_value + || HDstrcmp(filter_class.name, name_out) + || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED + | H5Z_FILTER_CONFIG_DECODE_ENABLED)) + TEST_ERROR + + /* Test H5Premove_filter */ + if(H5Premove_filter(gcpl2, H5Z_FILTER_RESERVED + 42) < 0) TEST_ERROR + H5E_BEGIN_TRY { + status = H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, + &flags_out, &cd_nelmts, &cd_value_out, (size_t)24, name_out, + &filter_config_out); + } H5E_END_TRY + if(status >= 0) TEST_ERROR + + /* Close remaining ids */ + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Pclose(gcpl2) < 0) TEST_ERROR + + /* Now create an object in the compressed group, creating intermediate + * groups, to verify that the filter pipeline is inherited for the groups + * that are created along the way */ + /* Reopen file */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Create lcpl, setting the "create intermediate groups" flag */ + if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_create_intermediate_group(lcpl, (unsigned)TRUE) < 0) TEST_ERROR + + /* Create new group, with missing intermediate groups, in compressed group */ + if((gid1 = H5Gcreate2(fid, "group1/group2/group3/group4", lcpl, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Close LCPL ID */ + if(H5Pclose(lcpl) < 0) TEST_ERROR + + /* Verify that new group doesn't have filters */ + if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl1) != 0) TEST_ERROR + + /* Close group & GCPL IDs */ + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Gclose(gid1) < 0) TEST_ERROR + + /* Open intermediate groups that were created and verify that they have filters */ + if((gid1 = H5Gopen2(fid, "group1/group2", H5P_DEFAULT)) < 0) TEST_ERROR + if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Gclose(gid1) < 0) TEST_ERROR + if((gid1 = H5Gopen2(fid, "group1/group2/group3", H5P_DEFAULT)) < 0) TEST_ERROR + if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Gclose(gid1) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + + /* Now create the same file with and without deflate, and verify that the + * file size is smaller with deflate */ + /* But only if the deflate filter is available */ + if((tri_ret = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0) TEST_ERROR + if(tri_ret) { + h5_stat_size_t filesize_filtered; + h5_stat_size_t filesize_unfiltered; + + /* Create gcpl, force use of dense storage */ + if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR + if(H5Pset_link_phase_change(fcpl, 2, 2) < 0) TEST_ERROR + + /* Create file */ + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + TEST_ERROR + + /* Create links in file */ + if(H5Lcreate_soft("/", fid, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file, get file size */ + if(H5Fclose(fid) < 0) TEST_ERROR + filesize_unfiltered = h5_get_file_size(filename, fapl); + + /* Set deflate fitler */ + if(H5Pset_deflate(fcpl, 6) < 0) TEST_ERROR + + /* Recreate the same file with the deflate filter */ + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file, get file size */ + if(H5Fclose(fid) < 0) TEST_ERROR + filesize_filtered = h5_get_file_size(filename, fapl); + + /* Check that the file size is smaller with the filter */ + if((double)filesize_filtered + > (filesize_unfiltered * FILTER_FILESIZE_MAX_FRACTION)) + TEST_ERROR + + /* Close */ + if(H5Pclose(fcpl) < 0) TEST_ERROR + } /* end if */ + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid1); + H5Gclose(gid2); + H5Fclose(fid); + H5Pclose(lcpl); + H5Pclose(gcpl1); + H5Pclose(gcpl2); + H5Pclose(fcpl); + } H5E_END_TRY; + return -1; +} /* end link_filters() */ + + +/*------------------------------------------------------------------------- * Function: corder_create_empty * * Purpose: Create an empty group with creation order indices @@ -13056,6 +13438,7 @@ main(void) nerrors += obj_visit(my_fapl, new_format) < 0 ? 1 : 0; nerrors += obj_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0; nerrors += obj_visit_stop(my_fapl, new_format) < 0 ? 1 : 0; + nerrors += link_filters(my_fapl, new_format) < 0 ? 1 : 0; /* Keep this test last, it's testing files that are used above */ /* do not do this for files used by external link tests */ diff --git a/test/tgenprop.c b/test/tgenprop.c index 1d3d766..8fb2e23 100644 --- a/test/tgenprop.c +++ b/test/tgenprop.c @@ -1478,7 +1478,7 @@ test_genprop_class_addprop(void) CHECK_I(cid, "H5Pcreate_class"); /* Check existence of an original property */ - ret = H5Pexist(cid,H5D_CRT_DATA_PIPELINE_NAME); + ret = H5Pexist(cid,H5O_CRT_PIPELINE_NAME); VERIFY(ret, 0, "H5Pexist"); /* Insert first property into class (with no callbacks) */ @@ -1490,7 +1490,7 @@ test_genprop_class_addprop(void) CHECK(pid, FAIL, "H5Pcreate"); /* Check existence of an original property */ - ret = H5Pexist(pid, H5D_CRT_DATA_PIPELINE_NAME); + ret = H5Pexist(pid, H5O_CRT_PIPELINE_NAME); VERIFY(ret, 1, "H5Pexist"); /* Check existence of added property */ -- cgit v0.12