diff options
Diffstat (limited to 'src/H5P.c')
-rw-r--r-- | src/H5P.c | 2772 |
1 files changed, 2451 insertions, 321 deletions
@@ -37,9 +37,92 @@ static intn interface_initialize_g = 0; #define INTERFACE_INIT H5P_init_interface static herr_t H5P_init_interface(void); +/* + * Predefined data types. These are initialized at runtime by + * H5P_init_interface() in this source file. + */ +hid_t H5P_NO_CLASS_g = FAIL; +hid_t H5P_FILE_CREATE_g = FAIL; +hid_t H5P_FILE_ACCESS_g = FAIL; +hid_t H5P_DATASET_CREATE_g = FAIL; +hid_t H5P_DATA_XFER_g = FAIL; +hid_t H5P_MOUNT_g = FAIL; + /* Declare a free list to manage the H5P_t struct */ H5FL_DEFINE_STATIC(H5P_t); + +/*------------------------------------------------------------------------- + * Function: H5P_init + * + * Purpose: Initialize the interface from some other layer. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, March 4, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_init(void) +{ + FUNC_ENTER(H5P_init, FAIL); + /* FUNC_ENTER() does all the work */ + FUNC_LEAVE(SUCCEED); +} + +/*-------------------------------------------------------------------------- +NAME + H5P_xor_name -- Generate an xor'ed value for a string +USAGE + uintn H5P_xor_name(s) + const char *s; IN: String to operate over +RETURNS + Always returns valid value +DESCRIPTION + Generates an xor'ed value for a string +--------------------------------------------------------------------------*/ +static uintn +H5P_xor_name(const char *s) +{ + uintn ret=0; + unsigned char temp; + + if(s!=NULL) + while(*s!='\0') { + temp=(ret>>24)&0xff; + ret <<= 8; + ret |= temp; + ret ^= *s++; + } + + return(ret); +} /* end H5P_xor_name() */ + +/*-------------------------------------------------------------------------- +NAME + H5P_hash_name -- Generate a hash value for a string +USAGE + uintn H5P_hash_name(s, hashsize) + const char *s; IN: String to operate over + uintn; IN: Size of hash table to clip against +RETURNS + Always returns valid value +DESCRIPTION + Generates an xor'ed value for a string +--------------------------------------------------------------------------*/ +static uintn +H5P_hash_name(const char *s, uintn hashsize) +{ + return(H5P_xor_name(s)%hashsize); +} /* end H5P_hash_name() */ + + /*-------------------------------------------------------------------------- NAME H5P_init_interface -- Initialize interface-specific information @@ -55,22 +138,14 @@ DESCRIPTION static herr_t H5P_init_interface(void) { + H5P_genclass_t *root_class; /* Pointer to root property list class created */ + H5P_genclass_t *pclass; /* Pointer to property list class to create */ herr_t ret_value = SUCCEED; intn i; herr_t status; FUNC_ENTER(H5P_init_interface, FAIL); - /* - * Make sure the file creation and file access default property lists are - * initialized since this might be done at run-time instead of compile - * time. - */ - if (H5F_init()<0) { - HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL, - "unable to initialize H5F and H5P interfaces"); - } - assert(H5P_NCLASSES <= H5I_TEMPLATE_MAX - H5I_TEMPLATE_0); /* @@ -79,15 +154,76 @@ H5P_init_interface(void) * publicly visible but atom groups aren't. */ for (i = 0; i < H5P_NCLASSES; i++) { - status = H5I_init_group((H5I_type_t)(H5I_TEMPLATE_0 +i), - H5I_TEMPID_HASHSIZE, 0, (H5I_free_t)H5P_close); - if (status < 0) ret_value = FAIL; + status = H5I_init_group((H5I_type_t)(H5I_TEMPLATE_0 +i), + H5I_TEMPID_HASHSIZE, 0, (H5I_free_t)H5P_close); + if (status < 0) + ret_value = FAIL; } + if (ret_value < 0) { - HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize atom group"); } + /* + * Initialize the Generic Property class & object groups. + */ + if (H5I_init_group(H5I_GENPROP_CLS, H5I_GENPROPCLS_HASHSIZE, 0, NULL) < 0) + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + "unable to initialize atom group"); + if (H5I_init_group(H5I_GENPROP_LST, H5I_GENPROPOBJ_HASHSIZE, 0, NULL) < 0) + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + "unable to initialize atom group"); + + /* Create root property list class */ + + /* Allocate the root class */ + if (NULL==(root_class = H5P_create_class (NULL,"none",H5P_NO_CLASS_HASH_SIZE,1,NULL,NULL,NULL,NULL))) + HRETURN_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); + + /* Register the root class */ + if ((H5P_NO_CLASS_g = H5I_register (H5I_GENPROP_CLS, root_class))<0) + HRETURN_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + + /* Register the file creation and file access property classes */ + + /* Allocate the file creation class */ + if (NULL==(pclass = H5P_create_class (root_class,"file create",H5P_FILE_CREATE_HASH_SIZE,1,NULL,NULL,NULL,NULL))) + HRETURN_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); + + /* Register the dataset creation class */ + if ((H5P_FILE_CREATE_g = H5I_register (H5I_GENPROP_CLS, pclass))<0) + HRETURN_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + + /* Allocate the file access class */ + if (NULL==(pclass = H5P_create_class (root_class,"file access",H5P_FILE_ACCESS_HASH_SIZE,1,NULL,NULL,NULL,NULL))) + HRETURN_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); + + /* Register the file access class */ + if ((H5P_DATA_XFER_g = H5I_register (H5I_GENPROP_CLS, pclass))<0) + HRETURN_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + + /* Register the dataset creation and data xfer property classes */ + + /* Allocate the dataset creation class */ + if (NULL==(pclass = H5P_create_class (root_class,"dataset create",H5P_DATASET_CREATE_HASH_SIZE,1,NULL,NULL,NULL,NULL))) + HRETURN_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); + + /* Register the dataset creation class */ + if ((H5P_DATASET_CREATE_g = H5I_register (H5I_GENPROP_CLS, pclass))<0) + HRETURN_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + + /* Allocate the data xfer class */ + if (NULL==(pclass = H5P_create_class (root_class,"data xfer",H5P_DATA_XFER_HASH_SIZE,1,NULL,NULL,NULL,NULL))) + HRETURN_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); + + /* Register the data xfer class */ + if ((H5P_DATA_XFER_g = H5I_register (H5I_GENPROP_CLS, pclass))<0) + HRETURN_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + +/* When do the "basic" properties for each of the library classes get added? */ +/* Who adds them? */ + FUNC_LEAVE(ret_value); } @@ -114,20 +250,29 @@ H5P_term_interface(void) intn i, n=0; if (interface_initialize_g) { - for (i=0; i<H5P_NCLASSES; i++) { - n += H5I_nmembers((H5I_type_t)(H5I_TEMPLATE_0+i)); - } - if (n) { - for (i=0; i<H5P_NCLASSES; i++) { - H5I_clear_group((H5I_type_t)(H5I_TEMPLATE_0+i), FALSE); - } - } else { - for (i=0; i<H5P_NCLASSES; i++) { - H5I_destroy_group((H5I_type_t)(H5I_TEMPLATE_0 + i)); - n++; /*H5I*/ - } - interface_initialize_g = 0; - } +/* Destroy HDF5 library property classes */ + for (i=0; i<H5P_NCLASSES; i++) + n += H5I_nmembers((H5I_type_t)(H5I_TEMPLATE_0+i)); + n += H5I_nmembers(H5I_GENPROP_CLS); + n += H5I_nmembers(H5I_GENPROP_LST); + if (n) { + for (i=0; i<H5P_NCLASSES; i++) + H5I_clear_group((H5I_type_t)(H5I_TEMPLATE_0+i), FALSE); + H5I_clear_group(H5I_GENPROP_CLS, FALSE); + H5I_clear_group(H5I_GENPROP_LST, FALSE); + } else { + for (i=0; i<H5P_NCLASSES; i++) { + H5I_destroy_group((H5I_type_t)(H5I_TEMPLATE_0 + i)); + n++; /*H5I*/ + } + + H5I_destroy_group(H5I_GENPROP_CLS); + n++; /*H5I*/ + H5I_destroy_group(H5I_GENPROP_LST); + n++; /*H5I*/ + + interface_initialize_g = 0; + } } return n; } @@ -179,18 +324,18 @@ H5Pcreate(H5P_class_t type) break; default: HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "unknown property list class"); + "unknown property list class"); } /* Copy the property list */ if (NULL==(new_plist=H5P_copy(type, src))) { - HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy default property list"); } /* Atomize the new property list */ if ((ret_value = H5P_create(type, new_plist)) < 0) { - HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to register property list"); } @@ -230,7 +375,7 @@ H5P_create(H5P_class_t type, H5P_t *plist) /* Atomize the new property list */ if ((ret_value=H5I_register((H5I_type_t)(H5I_TEMPLATE_0+type), plist))<0) { - HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to register property list"); } @@ -377,13 +522,15 @@ H5Pget_class(hid_t plist_id) if ((group = H5I_get_type(plist_id)) < 0 || #ifndef NDEBUG - group >= H5I_TEMPLATE_MAX || + group >= H5I_TEMPLATE_MAX || #endif - group < H5I_TEMPLATE_0) { - HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, H5P_NO_CLASS, + group < H5I_TEMPLATE_0) { + HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, H5P_NO_CLASS, "not a property list"); } + ret_value = (H5P_class_t)(group - H5I_TEMPLATE_0); + FUNC_LEAVE(ret_value); } @@ -414,12 +561,13 @@ H5P_get_class(hid_t plist_id) if ((group = H5I_get_type(plist_id)) < 0 || #ifndef NDEBUG - group >= H5I_TEMPLATE_MAX || + group >= H5I_TEMPLATE_MAX || #endif - group < H5I_TEMPLATE_0) { - HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, H5P_NO_CLASS, + group < H5I_TEMPLATE_0) { + HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, H5P_NO_CLASS, "not a property list"); } + ret_value = (H5P_class_t)(group - H5I_TEMPLATE_0); FUNC_LEAVE(ret_value); } @@ -651,15 +799,20 @@ H5Pget_version(hid_t plist_id, int *boot/*out*/, int *freelist/*out*/, /* Check arguments */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } + /* Get values */ - if (boot) *boot = plist->bootblock_ver; - if (freelist) *freelist = plist->freespace_ver; - if (stab) *stab = plist->objectdir_ver; - if (shhdr) *shhdr = plist->sharedheader_ver; + if (boot) + *boot = plist->bootblock_ver; + if (freelist) + *freelist = plist->freespace_ver; + if (stab) + *stab = plist->objectdir_ver; + if (shhdr) + *shhdr = plist->sharedheader_ver; FUNC_LEAVE(SUCCEED); } @@ -690,18 +843,21 @@ H5Pset_userblock(hid_t plist_id, hsize_t size) /* Check arguments */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } for (i=8; i<8*sizeof(hsize_t); i++) { - hsize_t p2 = 8==i ? 0 : ((hsize_t)1<<i); - if (size == p2) break; + hsize_t p2 = 8==i ? 0 : ((hsize_t)1<<i); + if (size == p2) + break; } + if (i>=8*sizeof(hsize_t)) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "userblock size is not valid"); } + /* Set value */ plist->userblock_size = size; @@ -735,12 +891,14 @@ H5Pget_userblock(hid_t plist_id, hsize_t *size) /* Check args */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } + /* Get value */ - if (size) *size = plist->userblock_size; + if (size) + *size = plist->userblock_size; FUNC_LEAVE(SUCCEED); } @@ -782,12 +940,12 @@ H5Pset_alignment(hid_t fapl_id, hsize_t threshold, hsize_t alignment) /* Check args */ if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || - NULL == (fapl = H5I_object (fapl_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (fapl = H5I_object (fapl_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } if (alignment<1) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "alignment must be positive"); } @@ -826,14 +984,16 @@ H5Pget_alignment(hid_t fapl_id, hsize_t *threshold/*out*/, /* Check args */ if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || - NULL == (fapl = H5I_object (fapl_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (fapl = H5I_object (fapl_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } /* Get values */ - if (threshold) *threshold = fapl->threshold; - if (alignment) *alignment = fapl->alignment; + if (threshold) + *threshold = fapl->threshold; + if (alignment) + *alignment = fapl->alignment; FUNC_LEAVE (SUCCEED); } @@ -865,29 +1025,30 @@ H5Pset_sizes(hid_t plist_id, size_t sizeof_addr, size_t sizeof_size) /* Check arguments */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } if (sizeof_addr) { - if (sizeof_addr != 2 && sizeof_addr != 4 && - sizeof_addr != 8 && sizeof_addr != 16) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "file haddr_t size is not valid"); - } + if (sizeof_addr != 2 && sizeof_addr != 4 && + sizeof_addr != 8 && sizeof_addr != 16) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "file haddr_t size is not valid"); + } } if (sizeof_size) { - if (sizeof_size != 2 && sizeof_size != 4 && - sizeof_size != 8 && sizeof_size != 16) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "file size_t size is not valid"); - } + if (sizeof_size != 2 && sizeof_size != 4 && + sizeof_size != 8 && sizeof_size != 16) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "file size_t size is not valid"); + } } + /* Set value */ if (sizeof_addr) - plist->sizeof_addr = sizeof_addr; + plist->sizeof_addr = sizeof_addr; if (sizeof_size) - plist->sizeof_size = sizeof_size; + plist->sizeof_size = sizeof_size; FUNC_LEAVE(SUCCEED); } @@ -921,15 +1082,16 @@ H5Pget_sizes(hid_t plist_id, /* Check args */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } + /* Get values */ if (sizeof_addr) - *sizeof_addr = plist->sizeof_addr; + *sizeof_addr = plist->sizeof_addr; if (sizeof_size) - *sizeof_size = plist->sizeof_size; + *sizeof_size = plist->sizeof_size; FUNC_LEAVE(SUCCEED); } @@ -971,19 +1133,20 @@ H5Pset_sym_k(hid_t plist_id, int ik, int lk) /* Check arguments */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } + /* Set values */ - if (ik > 0) { - plist->btree_k[H5B_SNODE_ID] = ik; - } - if (lk > 0) { - plist->sym_leaf_k = lk; - } + if (ik > 0) + plist->btree_k[H5B_SNODE_ID] = ik; + if (lk > 0) + plist->sym_leaf_k = lk; + FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5Pget_sym_k @@ -1012,18 +1175,19 @@ H5Pget_sym_k(hid_t plist_id, int *ik /*out */ , int *lk /*out */ ) /* Check arguments */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } /* Get values */ if (ik) - *ik = plist->btree_k[H5B_SNODE_ID]; + *ik = plist->btree_k[H5B_SNODE_ID]; if (lk) - *lk = plist->sym_leaf_k; + *lk = plist->sym_leaf_k; FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5Pset_istore_k @@ -1051,14 +1215,15 @@ H5Pset_istore_k(hid_t plist_id, int ik) /* Check arguments */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } if (ik <= 0) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "istore IK value must be positive"); } + /* Set value */ plist->btree_k[H5B_ISTORE_ID] = ik; @@ -1093,16 +1258,18 @@ H5Pget_istore_k(hid_t plist_id, int *ik /*out */ ) /* Check arguments */ if (H5P_FILE_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } + /* Get value */ if (ik) - *ik = plist->btree_k[H5B_ISTORE_ID]; + *ik = plist->btree_k[H5B_ISTORE_ID]; FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5Pset_layout @@ -1128,14 +1295,15 @@ H5Pset_layout(hid_t plist_id, H5D_layout_t layout) /* Check arguments */ if (H5P_DATASET_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (layout < 0 || layout >= H5D_NLAYOUTS) { - HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "raw data layout method is not valid"); } + /* Set value */ plist->layout = layout; @@ -1168,10 +1336,11 @@ H5Pget_layout(hid_t plist_id) /* Check arguments */ if (H5P_DATASET_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, H5D_LAYOUT_ERROR, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, H5D_LAYOUT_ERROR, "not a dataset creation property list"); } + FUNC_LEAVE(plist->layout); } @@ -1205,35 +1374,34 @@ H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]) /* Check arguments */ if (H5P_DATASET_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (ndims <= 0) { - HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "chunk dimensionality must be positive"); } if (ndims > H5S_MAX_RANK) { - HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "chunk dimensionality is too large"); } if (!dim) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no chunk dimensions specified"); } for (i=0; i<ndims; i++) { - if (dim[i] <= 0) { - HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, - "all chunk dimensions must be positive"); - } + if (dim[i] <= 0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, + "all chunk dimensions must be positive"); + } } /* Set value */ plist->layout = H5D_CHUNKED; plist->chunk_ndims = ndims; - for (i = 0; i < ndims; i++) { - plist->chunk_size[i] = dim[i]; - } + for (i = 0; i < ndims; i++) + plist->chunk_size[i] = dim[i]; FUNC_LEAVE(SUCCEED); } @@ -1268,17 +1436,17 @@ H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/) /* Check arguments */ if (H5P_DATASET_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (H5D_CHUNKED != plist->layout) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a chunked storage layout"); } - for (i=0; i<plist->chunk_ndims && i<max_ndims && dim; i++) { - dim[i] = plist->chunk_size[i]; - } + + for (i=0; i<plist->chunk_ndims && i<max_ndims && dim; i++) + dim[i] = plist->chunk_size[i]; FUNC_LEAVE(plist->chunk_ndims); } @@ -1321,48 +1489,47 @@ H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size) /* Check arguments */ if (H5P_DATASET_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (!name || !*name) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "no name given"); + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given"); } if (offset<0) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "negative external file offset"); } if (size<=0) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "zero size"); + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "zero size"); } if (plist->efl.nused>0 && - H5O_EFL_UNLIMITED==plist->efl.slot[plist->efl.nused-1].size) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + H5O_EFL_UNLIMITED==plist->efl.slot[plist->efl.nused-1].size) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "previous file size is unlimited"); } if (H5O_EFL_UNLIMITED!=size) { - for (idx=0, total=size; idx<plist->efl.nused; idx++, total=tmp) { - tmp = total + plist->efl.slot[idx].size; - if (tmp <= total) { - HRETURN_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, - "total external data size overflowed"); - } - } + for (idx=0, total=size; idx<plist->efl.nused; idx++, total=tmp) { + tmp = total + plist->efl.slot[idx].size; + if (tmp <= total) { + HRETURN_ERROR (H5E_EFL, H5E_OVERFLOW, FAIL, + "total external data size overflowed"); + } + } } /* Add to the list */ if (plist->efl.nused>=plist->efl.nalloc) { - intn na = plist->efl.nalloc + H5O_EFL_ALLOC; - H5O_efl_entry_t *x = H5MM_realloc (plist->efl.slot, - na*sizeof(H5O_efl_entry_t)); - if (!x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - plist->efl.nalloc = na; - plist->efl.slot = x; + intn na = plist->efl.nalloc + H5O_EFL_ALLOC; + H5O_efl_entry_t *x = H5MM_realloc (plist->efl.slot, + na*sizeof(H5O_efl_entry_t)); + + if (!x) { + HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } + plist->efl.nalloc = na; + plist->efl.slot = x; } idx = plist->efl.nused; plist->efl.slot[idx].name_offset = 0; /*not entered into heap yet*/ @@ -1401,8 +1568,8 @@ H5Pget_external_count(hid_t plist_id) /* Check arguments */ if (H5P_DATASET_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } @@ -1448,21 +1615,22 @@ H5Pget_external(hid_t plist_id, int idx, size_t name_size, char *name/*out*/, /* Check arguments */ if (H5P_DATASET_CREATE != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (idx<0 || idx>=plist->efl.nused) { - HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL, "external file index is out of range"); } /* Return values */ - if (name_size>0 && name) { - HDstrncpy (name, plist->efl.slot[idx].name, name_size); - } - if (offset) *offset = plist->efl.slot[idx].offset; - if (size) *size = plist->efl.slot[idx].size; + if (name_size>0 && name) + HDstrncpy (name, plist->efl.slot[idx].name, name_size); + if (offset) + *offset = plist->efl.slot[idx].offset; + if (size) + *size = plist->efl.slot[idx].size; FUNC_LEAVE (SUCCEED); } @@ -1500,43 +1668,43 @@ H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_info) H5TRACE3("e","iix",plist_id,driver_id,driver_info); if (H5I_VFL!=H5I_get_type(driver_id) || - NULL==H5I_object(driver_id)) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID"); + NULL==H5I_object(driver_id)) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID"); } if (H5P_FILE_ACCESS==H5P_get_class(plist_id)) { - if (NULL==(fapl=H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - - /* Remove old driver */ - assert(fapl->driver_id>=0); - H5FD_fapl_free(fapl->driver_id, fapl->driver_info); - H5I_dec_ref(fapl->driver_id); - - /* Add new driver */ - H5I_inc_ref(driver_id); - fapl->driver_id = driver_id; - fapl->driver_info = H5FD_fapl_copy(driver_id, driver_info); + if (NULL==(fapl=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + /* Remove old driver */ + assert(fapl->driver_id>=0); + H5FD_fapl_free(fapl->driver_id, fapl->driver_info); + H5I_dec_ref(fapl->driver_id); + + /* Add new driver */ + H5I_inc_ref(driver_id); + fapl->driver_id = driver_id; + fapl->driver_info = H5FD_fapl_copy(driver_id, driver_info); + } else if (H5P_DATA_XFER==H5P_get_class(plist_id)) { - if (NULL==(dxpl=H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - - /* Remove old driver */ - if (dxpl->driver_id>=0) - H5FD_dxpl_free(dxpl->driver_id, dxpl->driver_info); - - /* Add new driver */ - H5I_inc_ref(driver_id); - dxpl->driver_id = driver_id; - dxpl->driver_info = H5FD_fapl_copy(driver_id, driver_info); - + if (NULL==(dxpl=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + + /* Remove old driver */ + if (dxpl->driver_id>=0) + H5FD_dxpl_free(dxpl->driver_id, dxpl->driver_info); + + /* Add new driver */ + H5I_inc_ref(driver_id); + dxpl->driver_id = driver_id; + dxpl->driver_info = H5FD_fapl_copy(driver_id, driver_info); + } else { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access or data transfer property list"); } @@ -1580,19 +1748,21 @@ H5Pget_driver(hid_t plist_id) H5TRACE1("i","i",plist_id); if (H5P_FILE_ACCESS==H5P_get_class(plist_id) && - (fapl=H5I_object(plist_id))) { - ret_value = fapl->driver_id; + (fapl=H5I_object(plist_id))) { + ret_value = fapl->driver_id; } else if (H5P_DATA_XFER==H5P_get_class(plist_id) && (dxpl=H5I_object(plist_id))) { - ret_value = dxpl->driver_id; + ret_value = dxpl->driver_id; } else { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access or data transfer property list"); } - if (-2==ret_value) ret_value = H5FD_SEC2; + if (-2==ret_value) + ret_value = H5FD_SEC2; + FUNC_LEAVE(ret_value); } @@ -1628,15 +1798,15 @@ H5Pget_driver_info(hid_t plist_id) FUNC_ENTER(H5Pget_driver_info, NULL); if (H5P_FILE_ACCESS==H5P_get_class(plist_id) && - (fapl=H5I_object(plist_id))) { - ret_value = fapl->driver_info; + (fapl=H5I_object(plist_id))) { + ret_value = fapl->driver_info; } else if (H5P_DATA_XFER==H5P_get_class(plist_id) && (dxpl=H5I_object(plist_id))) { - ret_value = dxpl->driver_info; + ret_value = dxpl->driver_info; } else { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access or data transfer property list"); } @@ -1680,20 +1850,20 @@ H5Pset_cache(hid_t plist_id, int mdc_nelmts, /* Check arguments */ if (H5P_FILE_ACCESS!=H5P_get_class (plist_id) || - NULL==(fapl=H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(fapl=H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } if (mdc_nelmts<0) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "meta data cache size must be non-negative"); } if (rdcc_nelmts<0) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "raw data chunk cache nelmts must be non-negative"); } if (rdcc_w0<0.0 || rdcc_w0>1.0) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "raw data cache w0 value must be between 0.0 and 1.0 " "inclusive"); } @@ -1738,16 +1908,20 @@ H5Pget_cache(hid_t plist_id, int *mdc_nelmts, /* Check arguments */ if (H5P_FILE_ACCESS!=H5P_get_class (plist_id) || - NULL==(fapl=H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(fapl=H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } /* Get sizes */ - if (mdc_nelmts) *mdc_nelmts = fapl->mdc_nelmts; - if (rdcc_nelmts) *rdcc_nelmts = fapl->rdcc_nelmts; - if (rdcc_nbytes) *rdcc_nbytes = fapl->rdcc_nbytes; - if (rdcc_w0) *rdcc_w0 = fapl->rdcc_w0; + if (mdc_nelmts) + *mdc_nelmts = fapl->mdc_nelmts; + if (rdcc_nelmts) + *rdcc_nelmts = fapl->rdcc_nelmts; + if (rdcc_nbytes) + *rdcc_nbytes = fapl->rdcc_nbytes; + if (rdcc_w0) + *rdcc_w0 = fapl->rdcc_w0; FUNC_LEAVE (SUCCEED); } @@ -1786,12 +1960,12 @@ H5Pset_buffer(hid_t plist_id, size_t size, void *tconv, void *bkg) /* Check arguments */ if (H5P_DATA_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } if (size<=0) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "buffer size must not be zero"); } @@ -1830,14 +2004,16 @@ H5Pget_buffer(hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/) /* Check arguments */ if (H5P_DATA_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not a dataset transfer property list"); } /* Return values */ - if (tconv) *tconv = plist->tconv_buf; - if (bkg) *bkg = plist->bkg_buf; + if (tconv) + *tconv = plist->tconv_buf; + if (bkg) + *bkg = plist->bkg_buf; FUNC_LEAVE (plist->buf_size); } @@ -1876,8 +2052,8 @@ H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit) /* Check arguments */ if (H5P_DATA_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } @@ -1914,14 +2090,16 @@ H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/, /* Check arguments */ if (H5P_DATA_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } /* Return values */ - if (cache) *cache = plist->cache_hyper; - if (limit) *limit = plist->block_limit; + if (cache) + *cache = plist->cache_hyper; + if (limit) + *limit = plist->block_limit; FUNC_LEAVE (SUCCEED); } @@ -1955,8 +2133,8 @@ H5Pset_preserve(hid_t plist_id, hbool_t status) /* Check arguments */ if (H5P_DATA_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } @@ -1993,8 +2171,8 @@ H5Pget_preserve(hid_t plist_id) /* Check arguments */ if (H5P_DATA_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } @@ -2049,30 +2227,30 @@ H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, /* Check arguments */ if (H5P_DATA_XFER==H5P_get_class(plist_id)) { - HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, + HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, "transient pipelines are not supported yet"); } if (H5P_DATASET_CREATE!=H5P_get_class (plist_id) || - NULL==(plist=H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(plist=H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (filter<0 || filter>H5Z_FILTER_MAX) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identifier"); } if (flags & ~H5Z_FLAG_DEFMASK) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags"); } if (cd_nelmts>0 && !cd_values) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no client data values supplied"); } /* Do it */ if (H5Z_append(&(plist->pline), filter, flags, cd_nelmts, cd_values)<0) { - HRETURN_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add filter to pipeline"); } @@ -2113,12 +2291,12 @@ H5Pget_nfilters(hid_t plist_id) H5TRACE1("Is","i",plist_id); if (H5P_DATA_XFER==H5P_get_class(plist_id)) { - HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, + HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, "transient pipelines are not supported yet"); } if (H5P_DATASET_CREATE!=H5P_get_class(plist_id) || - NULL==(plist=H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(plist=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } @@ -2165,57 +2343,65 @@ H5Pget_filter(hid_t plist_id, int idx, unsigned int *flags/*out*/, /* Check arguments */ if (H5P_DATA_XFER==H5P_get_class(plist_id)) { - HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, H5Z_FILTER_ERROR, + HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, H5Z_FILTER_ERROR, "transient filters are not supported yet"); } if (H5P_DATASET_CREATE!=H5P_get_class (plist_id) || - NULL==(plist=H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5Z_FILTER_ERROR, + NULL==(plist=H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5Z_FILTER_ERROR, "not a dataset creation property list"); } if (idx<0 || (size_t)idx>=plist->pline.nfilters) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, "filter number is invalid"); } if (cd_nelmts || cd_values) { - if (cd_nelmts && *cd_nelmts>256) { - /* - * 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. - */ - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, - "probable uninitialized *cd_nelmts argument"); - } - if (cd_nelmts && *cd_nelmts>0 && !cd_values) { - HRETURN_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; + if (cd_nelmts && *cd_nelmts>256) { + /* + * 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. + */ + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, H5Z_FILTER_ERROR, + "probable uninitialized *cd_nelmts argument"); + } + if (cd_nelmts && *cd_nelmts>0 && !cd_values) { + HRETURN_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; } /* Output values */ - if (flags) *flags = plist->pline.filter[idx].flags; + if (flags) + *flags = plist->pline.filter[idx].flags; if (cd_values) { - for (i=0; i<plist->pline.filter[idx].cd_nelmts && i<*cd_nelmts; i++) { - cd_values[i] = plist->pline.filter[idx].cd_values[i]; - } + for (i=0; i<plist->pline.filter[idx].cd_nelmts && i<*cd_nelmts; i++) { + cd_values[i] = plist->pline.filter[idx].cd_values[i]; + } } - if (cd_nelmts) *cd_nelmts = plist->pline.filter[idx].cd_nelmts; + if (cd_nelmts) + *cd_nelmts = plist->pline.filter[idx].cd_nelmts; if (namelen>0 && name) { - const char *s = plist->pline.filter[idx].name; - if (!s) { - H5Z_class_t *cls = H5Z_find(plist->pline.filter[idx].id); - if (cls) s = cls->name; - } - if (s) HDstrncpy(name, s, namelen); - else name[0] = '\0'; + const char *s = plist->pline.filter[idx].name; + if (!s) { + H5Z_class_t *cls = H5Z_find(plist->pline.filter[idx].id); + + if (cls) + s = cls->name; + } + if (s) + HDstrncpy(name, s, namelen); + else + name[0] = '\0'; } FUNC_LEAVE (plist->pline.filter[idx].id); @@ -2252,23 +2438,23 @@ H5Pset_deflate(hid_t plist_id, unsigned level) /* Check arguments */ if (H5P_DATA_XFER==H5P_get_class(plist_id)) { - HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, + HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, "transient filter pipelines are not supported yet"); } if (H5P_DATASET_CREATE!=H5P_get_class (plist_id) || - NULL==(plist=H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(plist=H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (level>9) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid deflate level"); } /* Add the filter */ if (H5Z_append(&(plist->pline), H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &level)<0) { - HRETURN_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline"); } @@ -2304,15 +2490,18 @@ H5Pget_btree_ratios(hid_t plist_id, double *left/*out*/, double *middle/*out*/, /* Check arguments */ if (H5P_DATA_XFER!=H5P_get_class(plist_id) || - NULL==(plist=H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(plist=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } /* Get values */ - if (left) *left = plist->split_ratios[0]; - if (middle) *middle = plist->split_ratios[1]; - if (right) *right = plist->split_ratios[2]; + if (left) + *left = plist->split_ratios[0]; + if (middle) + *middle = plist->split_ratios[1]; + if (right) + *right = plist->split_ratios[2]; FUNC_LEAVE(SUCCEED); } @@ -2351,13 +2540,13 @@ H5Pset_btree_ratios(hid_t plist_id, double left, double middle, /* Check arguments */ if (H5P_DATA_XFER!=H5P_get_class(plist_id) || - NULL==(plist=H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(plist=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } if (left<0.0 || left>1.0 || middle<0.0 || middle>1.0 || - right<0.0 || right>1.0) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + right<0.0 || right>1.0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "split ratio must satisfy 0.0<=X<=1.0"); } @@ -2399,27 +2588,27 @@ H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value) /* Check arguments */ if (H5P_DATASET_CREATE!=H5P_get_class(plist_id) || - NULL==(plist=H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(plist=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); } if (H5I_DATATYPE!=H5I_get_type(type_id) || - NULL==(type=H5I_object(type_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + NULL==(type=H5I_object(type_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } if (!value) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value specified"); + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value specified"); } /* Set the fill value */ H5O_reset(H5O_FILL, &(plist->fill)); if (NULL==(plist->fill.type=H5T_copy(type, H5T_COPY_TRANSIENT))) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy data type"); } plist->fill.size = H5T_get_size(type); if (NULL==(plist->fill.buf=H5MM_malloc(plist->fill.size))) { - HRETURN_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, + HRETURN_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for fill value"); } HDmemcpy(plist->fill.buf, value, plist->fill.size); @@ -2462,16 +2651,16 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) /* Check arguments */ if (H5P_DATASET_CREATE!=H5P_get_class(plist_id) || - NULL==(plist=H5I_object(plist_id))) { - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(plist=H5I_object(plist_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation proprety list"); } if (H5I_DATATYPE!=H5I_get_type(type_id) || - NULL==(type=H5I_object(type_id))) { - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + NULL==(type=H5I_object(type_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } if (!value) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value output buffer"); } @@ -2481,20 +2670,20 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) * data type conversion might not have resulted in zero. */ if (NULL==plist->fill.buf) { - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "no fill value defined"); + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "no fill value defined"); } /* * Can we convert between the source and destination data types? */ if (NULL==(tpath=H5T_path_find(plist->fill.type, type, NULL, NULL))) { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst data types"); } src_id = H5I_register(H5I_DATATYPE, H5T_copy (plist->fill.type, H5T_COPY_TRANSIENT)); if (src_id<0) { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register data type"); } @@ -2504,34 +2693,38 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) * and destination. The app-supplied buffer might do okay. */ if (H5T_get_size(type)>=H5T_get_size(plist->fill.type)) { - buf = value; - if (tpath->cdata.need_bkg>=H5T_BKG_TEMP && - NULL==(bkg=H5MM_malloc(H5T_get_size(type)))) { - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - } + buf = value; + if (tpath->cdata.need_bkg>=H5T_BKG_TEMP && + NULL==(bkg=H5MM_malloc(H5T_get_size(type)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } } else { - if (NULL==(buf=H5MM_malloc(H5T_get_size(plist->fill.type)))) { - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - } - if (tpath->cdata.need_bkg>=H5T_BKG_TEMP) bkg = value; + if (NULL==(buf=H5MM_malloc(H5T_get_size(plist->fill.type)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } + if (tpath->cdata.need_bkg>=H5T_BKG_TEMP) + bkg = value; } HDmemcpy(buf, plist->fill.buf, H5T_get_size(plist->fill.type)); - + /* Do the conversion */ - if (H5T_convert(tpath, src_id, type_id, 1, 0, 0, buf, bkg, - H5P_DEFAULT)<0) { - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "data type conversion failed"); + if (H5T_convert(tpath, src_id, type_id, 1, 0, 0, buf, bkg, H5P_DEFAULT)<0) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "data type conversion failed"); } - if (buf!=value) HDmemcpy(value, buf, H5T_get_size(type)); + if (buf!=value) + HDmemcpy(value, buf, H5T_get_size(type)); ret_value = SUCCEED; - done: - if (buf!=value) H5MM_xfree(buf); - if (bkg!=value) H5MM_xfree(bkg); - if (src_id>=0) H5I_dec_ref(src_id); +done: + if (buf!=value) + H5MM_xfree(buf); + if (bkg!=value) + H5MM_xfree(bkg); + if (src_id>=0) + H5I_dec_ref(src_id); FUNC_LEAVE(ret_value); } @@ -2572,8 +2765,8 @@ H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref) /* Check args */ if (H5P_FILE_ACCESS!=H5P_get_class(fapl_id) || - NULL==(fapl=H5I_object(fapl_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + NULL==(fapl=H5I_object(fapl_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } @@ -2609,13 +2802,14 @@ H5Pget_gc_references(hid_t fapl_id, unsigned *gc_ref/*out*/) /* Check args */ if (H5P_FILE_ACCESS!=H5P_get_class(fapl_id) || - NULL==(fapl=H5I_object(fapl_id))) { + NULL==(fapl=H5I_object(fapl_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } /* Get values */ - if (gc_ref) *gc_ref = fapl->gc_ref; + if (gc_ref) + *gc_ref = fapl->gc_ref; FUNC_LEAVE (SUCCEED); } @@ -2695,7 +2889,7 @@ H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func/*out*/, /* Check arguments */ if (H5P_DATA_XFER!=H5P_get_class(plist_id) || - NULL==(plist=H5I_object(plist_id))) { + NULL==(plist=H5I_object(plist_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); } @@ -2712,3 +2906,1939 @@ H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func/*out*/, FUNC_LEAVE (SUCCEED); } + +/*-------------------------------------------------------------------------- + NAME + H5P_copy_prop + PURPOSE + Internal routine to copy a property + USAGE + H5P_genprop_t *H5P_copy_prop(oprop) + H5P_genprop_t *oprop; IN: Pointer to property to copy + RETURNS + Returns a pointer to the newly created property on success, + NULL on failure. + DESCRIPTION + Allocates memory and copies property information into a new property object. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5P_genprop_t * +H5P_copy_prop(H5P_genprop_t *oprop) +{ + H5P_genprop_t *prop=NULL; /* Pointer to new property copied */ + H5P_genprop_t *ret_value=NULL; /* Return value */ + + FUNC_ENTER (H5P_copy_prop, NULL); + + assert(oprop); + + /* Allocate the new property */ + if (NULL==(prop = H5MM_malloc (sizeof(H5P_genprop_t)))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* Copy basic property information */ + HDmemcpy(prop,oprop,sizeof(H5P_genprop_t)); + + /* Duplicate name */ + prop->name = HDstrdup(oprop->name); + + /* Duplicate current value, if it exists */ + if(oprop->value!=NULL) { + if (NULL==(prop->value = H5MM_malloc (prop->size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy(prop->value,oprop->value,prop->size); + } /* end if */ + + /* Duplicate default value, if it exists */ + if(oprop->def_value!=NULL) { + if (NULL==(prop->def_value = H5MM_malloc (prop->size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy(prop->def_value,oprop->def_value,prop->size); + } /* end if */ + + /* Reset the link to the next property */ + prop->next=NULL; + + /* Set return value */ + ret_value=prop; + +done: + /* Free any resources allocated */ + if(ret_value==NULL) { + if(prop!=NULL) { + if(prop->name!=NULL) + H5MM_xfree(prop->name); + if(prop->value!=NULL) + H5MM_xfree(prop->value); + if(prop->def_value!=NULL) + H5MM_xfree(prop->def_value); + H5MM_xfree(prop); + } /* end if */ + } /* end if */ + + FUNC_LEAVE (ret_value); +} /* H5P_copy_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_add_prop + PURPOSE + Internal routine to insert a property into a property hash table + USAGE + herr_t H5P_add_prop(hash, hashsize, prop) + H5P_gen_prop_t *hash[]; IN/OUT: Pointer to array of properties for hash table + uintn hashsize; IN: Size of hash table + H5P_genprop_t *prop; IN: Pointer to property to insert + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Inserts a property into a hash table of properties, using the hashed + property name. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_add_prop(H5P_genprop_t *hash[], uintn hashsize, H5P_genprop_t *prop) +{ + uintn loc; /* Hash table location */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER (H5P_add_prop, FAIL); + + assert(hash); + assert(hashsize>0); + assert(prop); + + /* Get correct hash table location */ + loc=H5P_hash_name(prop->name,hashsize); + + /* Insert property into hash table */ + prop->next=hash[loc]; + hash[loc]=prop; + +#ifdef LATER +done: +#endif /* LATER */ + FUNC_LEAVE (ret_value); +} /* H5P_add_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_find_prop + PURPOSE + Internal routine to check for a property in a hash table + USAGE + H5P_genprop_t *H5P_find_prop(hash, hashsize, name) + H5P_genprop_t *hash[]; IN: Pointer to array of properties for hash table + uintn hashsize; IN: Size of hash table + const char *name; IN: Name of property to check for + RETURNS + Returns pointer to property on success, NULL on failure. + DESCRIPTION + Checks for a property in a hash table of properties. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5P_genprop_t * +H5P_find_prop(H5P_genprop_t *hash[], uintn hashsize, const char *name) +{ + H5P_genprop_t *ret_value; /* Property pointer return value */ + uintn loc; /* Hash table location */ + + FUNC_ENTER (H5P_add_prop, NULL); + + assert(hash); + assert(hashsize>0); + assert(name); + + /* Get correct hash table location */ + loc=H5P_hash_name(name,hashsize); + + /* Locate property in list */ + ret_value=hash[loc]; + while(ret_value!=NULL) { + /* Check for name matching */ + if(HDstrcmp(ret_value->name,name)==0) + break; + } /* end while */ + +#ifdef LATER +done: +#endif /* LATER */ + FUNC_LEAVE (ret_value); +} /* H5P_find_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_free_prop + PURPOSE + Internal routine to destroy a property node + USAGE + herr_t H5P_free_prop(prop) + H5P_genprop_t *prop; IN: Pointer to property to destroy + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Releases all the memory for a property list. Does _not_ call the + properties 'close' callback, that should already have been done. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_free_prop(H5P_genprop_t *prop) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER (H5P_free_prop, FAIL); + + assert(prop); + + /* Release the property value and default value if they exist */ + if(prop->size>0) { + if(prop->value) + H5MM_xfree(prop->value); + if(prop->def_value) + H5MM_xfree(prop->def_value); + } /* end if */ + H5MM_xfree(prop->name); + H5MM_xfree(prop); + +#ifdef LATER +done: +#endif /* LATER */ + FUNC_LEAVE (ret_value); +} /* H5P_free_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_free_all_prop + PURPOSE + Internal routine to remove all properties from a property hash table + USAGE + herr_t H5P_free_all_prop(hash, hashsize) + H5P_gen_prop_t *hash[]; IN/OUT: Pointer to array of properties for hash table + uintn hashsize; IN: Size of hash table + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Remove all the properties from a property list. Calls the property + 'close' callback for each property removed. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_free_all_prop(H5P_genprop_t *hash[], uintn hashsize) +{ + H5P_genprop_t *tprop, *next;/* Temporary pointer to properties */ + uintn u; /* Local index variable */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER (H5P_free_all_prop, FAIL); + + assert(hash); + assert(hashsize>0); + + /* Work through all the properties... */ + for(u=0; u<hashsize; u++) { + tprop=hash[u]; + while(tprop!=NULL) { + /* Find next node right away, to avoid accessing the current node after it's been free'd */ + next=tprop->next; + + /* Call the close callback and ignore the return value, there's nothing we can do about it */ + if(tprop->close!=NULL) + (tprop->close)(tprop->name,&(tprop->value)); + + /* Free the property, ignoring return value, nothing we can do */ + H5P_free_prop(tprop); + + tprop=next; + } /* end while */ + } /* end for */ + +#ifdef LATER +done: +#endif /* LATER */ + FUNC_LEAVE (ret_value); +} /* H5P_free_all_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_access_class + PURPOSE + Internal routine to increment or decrement list & class dependancies on a + property list class + USAGE + herr_t H5P_access_class(pclass,mod) + H5P_genclass_t *pclass; IN: Pointer to class to modify + H5P_class_mod_t mod; IN: Type of modification to class + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Increment/Decrement the class or list dependancies for a given class. + This routine is the final arbiter on decisions about actually releasing a + class in memory, such action is only taken when the reference counts for + both dependent classes & lists reach zero. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER (H5P_access_class, FAIL); + + assert(pclass); + assert(mod>H5P_MOD_ERR && mod<H5P_MOD_MAX); + + switch(mod) { + case H5P_MOD_INC_CLS: /* Increment the dependant class count*/ + pclass->classes++; + break; + + case H5P_MOD_DEC_CLS: /* Decrement the dependant class count*/ + pclass->classes--; + break; + + case H5P_MOD_INC_LST: /* Increment the dependant list count*/ + pclass->plists++; + break; + + case H5P_MOD_DEC_LST: /* Decrement the dependant list count*/ + pclass->plists--; + break; + + case H5P_MOD_CHECK: /* NOOP, just check if we can delete the class */ + break; + + case H5P_MOD_ERR: + case H5P_MOD_MAX: + assert(0 && "Invalid H5P class modification"); + } /* end switch */ + + /* Check if we can release the class information now */ + if(pclass->deleted && pclass->plists==0 && pclass->classes==0 ) { + assert(pclass->name); + H5MM_xfree(pclass->name); + +/*!! Need to not make callbacks for these... */ + + /* Make calls to any property close callbacks which exist */ +/* H5P_free_all_prop(plist->props,plist->pclass->hashsize); */ + } /* end if */ + +#ifdef LATER +done: +#endif /* LATER */ + FUNC_LEAVE (ret_value); +} /* H5P_access_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_create_class + PURPOSE + Internal routine to create a new property list class. + USAGE + H5P_genclass_t H5P_create_class(par_class, name, hashsize, internal, + cls_create, create_data, cls_close, close_data) + H5P_genclass_t *par_class; IN: Pointer to parent class + const char *name; IN: Name of class we are creating + uintn hashsize; IN: Number of buckets in hash table + uintn internal; IN: Whether this is an internal class or not + H5P_cls_create_func_t; IN: The callback function to call when each + property list in this class is created. + void *create_data; IN: Pointer to user data to pass along to class + creation callback. + H5P_cls_close_func_t; IN: The callback function to call when each + property list in this class is closed. + void *close_data; IN: Pointer to user data to pass along to class + close callback. + RETURNS + Returns a pointer to the newly created property list class on success, + NULL on failure. + DESCRIPTION + Allocates memory and attaches a class to the property list class hierarchy. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5P_genclass_t * +H5P_create_class(H5P_genclass_t *par_class, const char *name, uintn hashsize, uintn internal, + H5P_cls_create_func_t cls_create, void *create_data, + H5P_cls_close_func_t cls_close, void *close_data + ) +{ + H5P_genclass_t *pclass; /* Property list class created */ + H5P_genclass_t *ret_value=NULL; /* return value */ + + FUNC_ENTER (H5P_create_class, NULL); + + assert(name); + /* Allow internal classes to break some rules */ + /* (This allows the root of the tree to be created with this routine -QAK) */ + if(!internal) { + assert(par_class); + assert(hashsize>0); + } + + /* Allocate room for the class & it's hash table of properties */ + if (NULL==(pclass = H5MM_calloc (sizeof(H5P_genclass_t)+((hashsize-1)*sizeof(H5P_genprop_t *))))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); + + /* Set class state */ + pclass->parent = par_class; + pclass->name = HDstrdup(name); + pclass->nprops = 0; /* Classes are created without properties initially */ + pclass->hashsize = hashsize; + pclass->plists = 0; /* No properties lists of this class yet */ + pclass->classes = 0; /* No classes derived from this class yet */ + pclass->internal = internal; + pclass->deleted = 0; /* Not deleted yet... :-) */ + + /* Set callback functions and pass-along data */ + pclass->create_func = cls_create; + pclass->create_data = create_data; + pclass->close_func = cls_close; + pclass->close_data = close_data; + + /* Increment parent class's derived class value */ + if(par_class!=NULL) + if(H5P_access_class(par_class,H5P_MOD_INC_CLS)<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment parent class ref count"); + + /* Set return value */ + ret_value=pclass; + +done: + /* Free any resources allocated */ + if(ret_value==NULL) { + if(pclass!=NULL) + H5MM_xfree(pclass); + } + + FUNC_LEAVE (ret_value); +} /* H5P_create_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pcreate_class + PURPOSE + Create a new property list class. + USAGE + hid_t H5Pcreate_class(parent, name, hashsize, cls_create, create_data, + cls_close, close_data) + hid_t parent; IN: Property list class ID of parent class + const char *name; IN: Name of class we are creating + uintn hashsize; IN: Number of buckets in hash table + H5P_cls_create_func_t cls_create; IN: The callback function to call + when each property list in this class is + created. + void *create_data; IN: Pointer to user data to pass along to class + creation callback. + H5P_cls_close_func_t cls_close; IN: The callback function to call + when each property list in this class is + closed. + void *close_data; IN: Pointer to user data to pass along to class + close callback. + RETURNS + Returns a valid property list class ID on success, NULL on failure. + DESCRIPTION + Allocates memory and attaches a class to the property list class hierarchy. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hid_t +H5Pcreate_class(hid_t parent, const char *name, unsigned hashsize, + H5P_cls_create_func_t cls_create, void *create_data, + H5P_cls_close_func_t cls_close, void *close_data + ) +{ + H5P_genclass_t *par_class = NULL; /* Pointer to the parent class */ + H5P_genclass_t *pclass = NULL; /* Property list class created */ + hid_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER(H5Pcreate_class, FAIL); + + /* Check arguments. */ + if (H5P_DEFAULT!=parent && (H5I_GENPROP_CLS!=H5I_get_type(parent))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); + if (hashsize==0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hashsize too small"); + if ((create_data!=NULL && cls_create==NULL) || (close_data!=NULL && cls_close==NULL)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data specified, but no callback provided"); + + /* Get the pointer to the parent class */ + if(parent==H5P_DEFAULT) + par_class=NULL; + else { + if (NULL == (par_class = H5I_object(parent))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't retrieve parent class"); + } /* end else */ + + /* Create the new property list class */ + if (NULL==(pclass=H5P_create_class(par_class, name, hashsize, 0, cls_create, create_data, cls_close, close_data))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list class"); + + /* Get an atom for the class */ + if ((ret_value = H5I_register(H5I_GENPROP_CLS, pclass))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list class"); + +done: + if (ret_value<0 && pclass) + H5P_close_class(pclass); + + FUNC_LEAVE(ret_value); +} /* H5Pcreate_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_create_list + PURPOSE + Internal routine to create a new property list of a property list class. + USAGE + H5P_genplist_t *H5P_create_list(class) + H5P_genclass_t *class; IN: Property list class create list from + RETURNS + Returns a pointer to the newly created property list on success, + NULL on failure. + DESCRIPTION + Creates a property list of a given class. If a 'create' callback + exists for the property list class, it is called before the + property list is passed back to the user. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + If this routine is called from a library routine other than + H5Pcreate_list, the calling routine is responsible for getting an ID for + the property list and calling the class 'create' callback (if one exists) + and also setting the "class_init" flag. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +H5P_genplist_t *H5P_create_list(H5P_genclass_t *class) +{ + H5P_genclass_t *tclass=NULL; /* Temporary class pointer */ + H5P_genplist_t *plist=NULL; /* New property list created */ + H5P_genplist_t *ret_value=NULL; /* return value */ + H5P_genprop_t *tmp; /* Temporary pointer to parent class properties */ + H5P_genprop_t *pcopy; /* Copy of property to insert into class */ + uintn u; /* Local index variable */ + + FUNC_ENTER (H5P_create_list, NULL); + + assert(class); + + /* + * Create new property list object + */ + + /* Allocate room for the property list & it's hash table of properties */ + if (NULL==(plist = H5MM_calloc (sizeof(H5P_genplist_t)+((class->hashsize-1)*sizeof(H5P_genprop_t *))))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); + + /* Set class state */ + plist->pclass = class; + plist->nprops = 0; /* Initially the plist has the same number of properties as the class */ + plist->class_init = 0; /* Initially, wait until the class callback finishes to set */ + + /* + * Copy class properties (up through list of parent classes also), + * initialize each with default value & make property 'create' callback. + */ + tclass=class; + while(tclass!=NULL) { + if(tclass->nprops>0) { + /* Walk through the hash table */ + for(u=0; u<tclass->hashsize; u++) { + tmp=tclass->props[u]; + /* Walk through the list of properties at each hash location */ + while(tmp!=NULL) { + /* Check for property already existing in list */ + if(H5P_find_prop(plist->props,class->hashsize,tmp->name)==NULL) { + /* Make a copy of the class's property */ + if((pcopy=H5P_copy_prop(tmp))==NULL) + HGOTO_ERROR (H5E_PLIST, H5E_CANTCOPY, NULL,"Can't copy property"); + + /* Create initial value from default value for non-zero sized properties */ + if(pcopy->size>0) { + /* Properties from the class should have any values yet, but should have a default */ + assert(pcopy->value==NULL); + assert(pcopy->def_value); + + /* Allocate space for the property value & copy default value */ + if (NULL==(pcopy->value = H5MM_malloc (pcopy->size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + HDmemcpy(pcopy->value,pcopy->def_value,pcopy->size); + } /* end if */ + + /* Call property creation callback, if it exists */ + if(pcopy->create) { + if((pcopy->create)(pcopy->name,&(pcopy->value))<0) { + H5P_free_prop(pcopy); + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't initialize property"); + } /* end if */ + } /* end if */ + + /* Insert the initialized property into the property list */ + if(H5P_add_prop(plist->props,class->hashsize,pcopy)<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINSERT, NULL,"Can't insert property into class"); + } /* end if */ + + /* Go to next registered property in class */ + tmp=tmp->next; + } /* end while */ + } /* end for */ + } /* end if */ + + /* Go up to parent class */ + tclass=tclass->parent; + } /* end while */ + + /* Increment the number of property lists derived from class */ + if(H5P_access_class(plist->pclass,H5P_MOD_INC_LST)<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't increment class ref count"); + + /* Set return value */ + ret_value=plist; + +done: + /* Release resources allocated on failure */ + if(ret_value==NULL) { + if(plist!=NULL) { + /* Close & free all the properties */ + H5P_free_all_prop(plist->props,class->hashsize); + + /* Decrement the number of property lists derived from the class */ + class->plists--; + } /* end if */ + } /* end if */ + + FUNC_LEAVE (ret_value); +} /* H5P_create_list() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pcreate_list + PURPOSE + Routine to create a new property list of a property list class. + USAGE + hid_t H5Pcreate_list(cls_id) + hid_t cls_id; IN: Property list class create list from + RETURNS + Returns a valid property list ID on success, NULL on failure. + DESCRIPTION + Creates a property list of a given class. If a 'create' callback + exists for the property list class, it is called before the + property list is passed back to the user. If 'create' callbacks exist for + any individual properties in the property list, they are called before the + class 'create' callback. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +hid_t H5Pcreate_list(hid_t cls_id) +{ + H5P_genclass_t *pclass; /* Property list class to modify */ + H5P_genplist_t *plist; /* Property list created */ + hid_t plist_id=FAIL; /* Property list ID */ + hid_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pcreate_list, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_CLS != H5I_get_type(cls_id) || NULL == (pclass = H5I_object(cls_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list class"); + + /* Create the new property list */ + if ((plist=H5P_create_list(pclass))==NULL) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list"); + + /* Get an atom for the property list */ + if ((plist_id = H5I_register(H5I_GENPROP_LST, plist))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to atomize property list"); + + /* Call the class callback (if it exists) now that we have the property list ID */ + if(plist->pclass->create_func!=NULL) { + if((plist->pclass->create_func)(plist_id,plist->pclass->create_data)<0) { + /* Delete ID, ignore return value */ + H5I_remove(plist_id); + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL,"Can't initialize property"); + } /* end if */ + } /* end if */ + + /* Set the class initialization flag */ + plist->class_init=1; + + /* Set the return value */ + ret_value=plist_id; + +done: + if (ret_value<0 && plist) + H5P_close_list(plist); + + FUNC_LEAVE (ret_value); +} /* H5Pcreate_list() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_register + PURPOSE + Internal routine to register a new property in a property list class. + USAGE + herr_t H5P_register(class, name, size, default, prp_create, prp_set, prp_get, prp_close) + H5P_genclass_t *class; IN: Property list class to close + const char *name; IN: Name of property to register + size_t size; IN: Size of property in bytes + void *def_value; IN: Pointer to buffer containing default value + for property in newly created property lists + H5P_prp_create_func_t prp_create; IN: Function pointer to property + creation callback + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Registers a new property with a property list class. The property will + exist in all property list objects of that class after this routine is + finished. The name of the property must not already exist. The default + property value must be provided and all new property lists created with this + property will have the property value set to the default provided. Any of + the callback routines may be set to NULL if they are not needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'default' pointer for a + zero-sized property may be set to NULL. The property 'create' & 'close' + callbacks are called for zero-sized properties, but the 'set' and 'get' + callbacks are never called. + + The 'create' callback is called when a new property list with this + property is being created. H5P_prp_create_func_t is defined as: + typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, + void **initial_value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being created. + const char *name; IN: The name of the property being modified. + void **initial_value; IN/OUT: The initial value for the property being created. + (The 'default' value passed to H5Pregister) + The 'create' routine may modify the value to be set and those changes will + be stored as the initial value of the property. If the 'create' routine + returns a negative value, the new property value is not copied into the + property and the property list creation routine returns an error value. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + void **value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + void **new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + void **value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_register(H5P_genclass_t *class, const char *name, size_t size, + void *def_value, H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, + H5P_prp_get_func_t prp_get, H5P_prp_close_func_t prp_close) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_register, FAIL); + + assert(class); + assert(name); + assert((size>0 && def_value!=NULL) || (size==0)); + +/* Check for duplicate named properties */ +/* Check if class needs to be split because property lists or classes have been */ +/* created since the last modification was made to the class. Insert property */ +/* into property list class, increment modification made to class, reset */ +/* information about property lists & classes created */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_register() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pregister + PURPOSE + Routine to register a new property in a property list class. + USAGE + herr_t H5Pregister(class, name, size, default, prp_create, prp_set, prp_get, prp_close) + hid_t class; IN: Property list class to close + const char *name; IN: Name of property to register + size_t size; IN: Size of property in bytes + void *def_value; IN: Pointer to buffer containing default value + for property in newly created property lists + H5P_prp_create_func_t prp_create; IN: Function pointer to property + creation callback + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Registers a new property with a property list class. The property will + exist in all property list objects of that class after this routine is + finished. The name of the property must not already exist. The default + property value must be provided and all new property lists created with this + property will have the property value set to the default provided. Any of + the callback routines may be set to NULL if they are not needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'default' pointer for a + zero-sized property may be set to NULL. The property 'create' & 'close' + callbacks are called for zero-sized properties, but the 'set' and 'get' + callbacks are never called. + + The 'create' callback is called when a new property list with this + property is being created. H5P_prp_create_func_t is defined as: + typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name, + void **initial_value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being created. + const char *name; IN: The name of the property being modified. + void **initial_value; IN/OUT: The initial value for the property being created. + (The 'default' value passed to H5Pregister) + The 'create' routine may modify the value to be set and those changes will + be stored as the initial value of the property. If the 'create' routine + returns a negative value, the new property value is not copied into the + property and the property list creation routine returns an error value. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + void **value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + void **new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + void **value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Pregister(hid_t cls_id, const char *name, size_t size, void *def_value, + H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, + H5P_prp_get_func_t prp_get, H5P_prp_close_func_t prp_close) +{ + H5P_genclass_t *pclass; /* Property list class to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pregister, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_CLS != H5I_get_type(cls_id) || NULL == (pclass = H5I_object(cls_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid class name"); + if (size>0 && def_value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); + + /* Create the new property list class */ + if ((ret_value=H5P_register(pclass,name,size,def_value,prp_create,prp_set,prp_get,prp_close))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in class"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Pregister() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_insert + PURPOSE + Internal routine to insert a new property in a property list. + USAGE + herr_t H5P_insert(plist, name, size, value, prp_set, prp_get, prp_close) + H5P_genplist_t *plist; IN: Property list to add property to + const char *name; IN: Name of property to add + size_t size; IN: Size of property in bytes + void *value; IN: Pointer to the value for the property + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Inserts a temporary property into a property list. The property will + exist only in this property list object. The name of the property must not + already exist. The value must be provided unless the property is zero- + sized. Any of the callback routines may be set to NULL if they are not + needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'value' pointer for a + zero-sized property may be set to NULL. The property 'close' callback is + called for zero-sized properties, but the 'set' and 'get' callbacks are + never called. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + void **value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + void **new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + void **value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, + void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + There is no 'create' callback routine for temporary property list + objects, the initial value is assumed to have any necessary setup already + performed on it. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, + void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, + H5P_prp_close_func_t prp_close) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_insert, FAIL); + + assert(plist); + assert(name); + assert((size>0 && value!=NULL) || (size==0)); + +/* Check for duplicate named properties */ +/* Insert property into property list */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_insert() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pinsert + PURPOSE + Routine to insert a new property in a property list. + USAGE + herr_t H5Pinsert(plist, name, size, value, prp_set, prp_get, prp_close) + hid_t plist; IN: Property list to add property to + const char *name; IN: Name of property to add + size_t size; IN: Size of property in bytes + void *value; IN: Pointer to the value for the property + H5P_prp_set_func_t prp_set; IN: Function pointer to property set callback + H5P_prp_get_func_t prp_get; IN: Function pointer to property get callback + H5P_prp_close_func_t prp_close; IN: Function pointer to property close + callback + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Inserts a temporary property into a property list. The property will + exist only in this property list object. The name of the property must not + already exist. The value must be provided unless the property is zero- + sized. Any of the callback routines may be set to NULL if they are not + needed. + + Zero-sized properties are allowed and do not store any data in the + property list. These may be used as flags to indicate the presence or + absence of a particular piece of information. The 'value' pointer for a + zero-sized property may be set to NULL. The property 'close' callback is + called for zero-sized properties, but the 'set' and 'get' callbacks are + never called. + + The 'set' callback is called before a new value is copied into the + property. H5P_prp_set_func_t is defined as: + typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, + void **value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being modified. + const char *name; IN: The name of the property being modified. + void **new_value; IN/OUT: The value being set for the property. + The 'set' routine may modify the value to be set and those changes will be + stored as the value of the property. If the 'set' routine returns a + negative value, the new property value is not copied into the property and + the property list set routine returns an error value. + + The 'get' callback is called before a value is retrieved from the + property. H5P_prp_get_func_t is defined as: + typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, + void *value); + where the parameters to the callback function are: + hid_t prop_id; IN: The ID of the property list being queried. + const char *name; IN: The name of the property being queried. + void **value; IN/OUT: The value being retrieved for the property. + The 'get' routine may modify the value to be retrieved and those changes + will be returned to the calling function. If the 'get' routine returns a + negative value, the property value is returned and the property list get + routine returns an error value. + + The 'close' callback is called when a property list with this + property is being destroyed. H5P_prp_close_func_t is defined as: + typedef herr_t (*H5P_prp_close_func_t)(const char *name, void *value); + where the parameters to the callback function are: + const char *name; IN: The name of the property being closed. + void *value; IN: The value of the property being closed. + The 'close' routine may modify the value passed in, but the value is not + used by the library when the 'close' routine returns. If the + 'close' routine returns a negative value, the property list close + routine returns an error value but the property list is still closed. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback function may be useful to range check the value being + set for the property or may perform some tranformation/translation of the + value set. The 'get' callback would then [probably] reverse the + transformation, etc. A single 'get' or 'set' callback could handle + multiple properties by performing different actions based on the property + name or other properties in the property list. + + There is no 'create' callback routine for temporary property list + objects, the initial value is assumed to have any necessary setup already + performed on it. + + I would like to say "the property list is not closed" when a 'close' + routine fails, but I don't think that's possible due to other properties in + the list being successfully closed & removed from the property list. I + suppose that it would be possible to just remove the properties which have + successful 'close' callbacks, but I'm not happy with the ramifications + of a mangled, un-closable property list hanging around... Any comments? -QAK + + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Pinsert(hid_t plist_id, const char *name, size_t size, void *value, + H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, + H5P_prp_close_func_t prp_close) +{ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pinsert, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_LST != H5I_get_type(plist_id) || NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if (size>0 && value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "properties >0 size must have default"); + + /* Create the new property list class */ + if ((ret_value=H5P_insert(plist,name,size,value,prp_set,prp_get,prp_close))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to register property in plist"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Pinsert() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_set + PURPOSE + Internal routine to set a property's value in a property list. + USAGE + herr_t H5P_set(plist, name, value) + H5P_genplist_t *plist; IN: Property list to find property in + const char *name; IN: Name of property to set + void *value; IN: Pointer to the value for the property + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Sets a new value for a property in a property list. The property name + must exist or this routine will fail. If there is a 'set' callback routine + registered for this property, the 'value' will be passed to that routine and + any changes to the 'value' will be used when setting the property value. + The information pointed at by the 'value' pointer (possibly modified by the + 'set' callback) is copied into the property list value and may be changed + by the application making the H5Pset call without affecting the property + value. + + If the 'set' callback routine returns an error, the property value will + not be modified. This routine may not be called for zero-sized properties + and will return an error in that case. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_set(H5P_genplist_t *plist, const char *name, void *value) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_set, FAIL); + + assert(plist); + assert(name); + assert(value); + +/* Check for property size >0 */ +/* Make a copy of the value */ +/* Pass to 'set' callback if it exists */ +/* Copy new [possibly changed] value into property value */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_set() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pset + PURPOSE + Routine to set a property's value in a property list. + USAGE + herr_t H5P_set(plist_id, name, value) + hid_t plist_id; IN: Property list to find property in + const char *name; IN: Name of property to set + void *value; IN: Pointer to the value for the property + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Sets a new value for a property in a property list. The property name + must exist or this routine will fail. If there is a 'set' callback routine + registered for this property, the 'value' will be passed to that routine and + any changes to the 'value' will be used when setting the property value. + The information pointed at by the 'value' pointer (possibly modified by the + 'set' callback) is copied into the property list value and may be changed + by the application making the H5Pset call without affecting the property + value. + + If the 'set' callback routine returns an error, the property value will + not be modified. This routine may not be called for zero-sized properties + and will return an error in that case. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Pset(hid_t plist_id, const char *name, void *value) +{ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pset, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_LST != H5I_get_type(plist_id) || NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if (value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value"); + + /* Create the new property list class */ + if ((ret_value=H5P_set(plist,name,value))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to set value in plist"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Pset() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_exist + PURPOSE + Internal routine to query the existance of a property in a property list. + USAGE + herr_t H5P_exist(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to check for + RETURNS + Success: Positive if the property exists in the property list, zero + if the property does not exist. + Failure: negative value + DESCRIPTION + This routine checks if a property exists within a property list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_exist(H5P_genplist_t *plist, const char *name) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_exist, FAIL); + + assert(plist); + assert(name); + +/* Check for property in property list */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_exist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pexist + PURPOSE + Routine to query the existance of a property in a property list. + USAGE + herr_t H5P_exist(plist_id, name) + hid_t plist_id; IN: Property list ID to check + const char *name; IN: Name of property to check for + RETURNS + Success: Positive if the property exists in the property list, zero + if the property does not exist. + Failure: negative value + DESCRIPTION + This routine checks if a property exists within a property list. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Pexist(hid_t plist_id, const char *name) +{ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pexist, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_LST != H5I_get_type(plist_id) || NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + + /* Create the new property list class */ + if ((ret_value=H5P_exist(plist,name))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to set value in plist"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Pexist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get_size + PURPOSE + Internal routine to query the size of a property in a property list. + USAGE + herr_t H5P_get_size(plist, name) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + RETURNS + Success: Size of property value in bytes. + Failure: negative value + DESCRIPTION + This routine returns the size of a property's value in bytes. Zero- + sized properties are allowed and return 0. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_get_size(H5P_genplist_t *plist, const char *name) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_get_size, FAIL); + + assert(plist); + assert(name); + +/* Check for property in property list */ +/* Query property size */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_get_size() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pget_size + PURPOSE + Routine to query the size of a property in a property list. + USAGE + herr_t H5Pget_size(plist_id, name) + hid_t plist_id; IN: Property list to check + const char *name; IN: Name of property to query + RETURNS + Success: Size of property value in bytes. + Failure: negative value + DESCRIPTION + This routine returns the size of a property's value in bytes. Zero- + sized properties are allowed and return 0. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Pget_size(hid_t plist_id, const char *name) +{ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pget_size, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_LST != H5I_get_type(plist_id) || NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + + /* Create the new property list class */ + if ((ret_value=H5P_get_size(plist,name))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query size in plist"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Pget_size() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_get + PURPOSE + Internal routine to query the value of a property in a property list. + USAGE + herr_t H5P_get_size(plist, name, value) + H5P_genplist_t *plist; IN: Property list to check + const char *name; IN: Name of property to query + void *value; OUT: Pointer to the buffer for the property value + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Retrieves a copy of the value for a property in a property list. The + property name must exist or this routine will fail. If there is a + 'get' callback routine registered for this property, the copy of the + value of the property will first be passed to that routine and any changes + to the copy of the value will be used when returning the property value + from this routine. + If the 'get' callback routine returns an error, 'value' will not be + modified and this routine will return an error. This routine may not be + called for zero-sized properties. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_get(H5P_genplist_t *plist, const char *name, void *value) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_get, FAIL); + + assert(plist); + assert(name); + assert(value); + +/* Find the property in the property list */ +/* Check for property size >0 */ +/* Make a copy of the value */ +/* Pass to 'get' callback if it exists */ +/* Copy [possibly changed] value into user's buffer */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_get() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pget + PURPOSE + Routine to query the value of a property in a property list. + USAGE + herr_t H5P_get_size(plist_id, name, value) + hid_t plist_id; IN: Property list to check + const char *name; IN: Name of property to query + void *value; OUT: Pointer to the buffer for the property value + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Retrieves a copy of the value for a property in a property list. The + property name must exist or this routine will fail. If there is a + 'get' callback routine registered for this property, the copy of the + value of the property will first be passed to that routine and any changes + to the copy of the value will be used when returning the property value + from this routine. + If the 'get' callback routine returns an error, 'value' will not be + modified and this routine will return an error. This routine may not be + called for zero-sized properties. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Pget(hid_t plist_id, const char *name, void * value) +{ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pget, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_LST != H5I_get_type(plist_id) || NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + if (value==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalied property value"); + + /* Create the new property list class */ + if ((ret_value=H5P_get(plist,name,value))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to query property value"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Pget() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_remove + PURPOSE + Internal routine to remove a property from a property list. + USAGE + herr_t H5P_remove(plist, name) + H5P_genplist_t *plist; IN: Property list to modify + const char *name; IN: Name of property to remove + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Removes a property from a property list. Both properties which were + in existance when the property list was created (i.e. properties registered + with H5Pregister) and properties added to the list after it was created + (i.e. added with H5Pinsert) may be removed from a property list. + Properties do not need to be removed a property list before the list itself + is closed, they will be released automatically when H5Pclose is called. + The 'close' callback for this property is called before the property is + release, if the callback exists. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_remove(H5P_genplist_t *plist, const char *name) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_remove, FAIL); + + assert(plist); + assert(name); + +/* Find the property in the property list */ +/* Get value for property */ +/* Pass to 'remove' callback if it exists */ +/* Remove property from property list */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_remove() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Premove + PURPOSE + Routine to remove a property from a property list. + USAGE + herr_t H5Premove(plist_id, name) + hid_t plist_id; IN: Property list to modify + const char *name; IN: Name of property to remove + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Removes a property from a property list. Both properties which were + in existance when the property list was created (i.e. properties registered + with H5Pregister) and properties added to the list after it was created + (i.e. added with H5Pinsert) may be removed from a property list. + Properties do not need to be removed a property list before the list itself + is closed, they will be released automatically when H5Pclose is called. + The 'close' callback for this property is called before the property is + release, if the callback exists. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Premove(hid_t plist_id, const char *name) +{ + H5P_genplist_t *plist; /* Property list to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Premove, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_LST != H5I_get_type(plist_id) || NULL == (plist = H5I_object(plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + + /* Create the new property list class */ + if ((ret_value=H5P_remove(plist,name))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to remove property"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Premove() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_unregister + PURPOSE + Internal routine to remove a property from a property list class. + USAGE + herr_t H5P_unregister(pclass, name) + H5P_genclass_t *pclass; IN: Property list class to modify + const char *name; IN: Name of property to remove + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Removes a property from a property list class. Future property lists + created of that class will not contain this property. Existing property + lists containing this property are not affected. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_unregister(H5P_genclass_t *pclass, const char *name) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_unregister, FAIL); + + assert(pclass); + assert(name); + +/* Find the property in the property list class */ +/* Remove property from property list class */ + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_unregister() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Punregister + PURPOSE + Routine to remove a property from a property list class. + USAGE + herr_t H5Punregister(pclass_id, name) + hid_t pclass_id; IN: Property list class to modify + const char *name; IN: Name of property to remove + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Removes a property from a property list class. Future property lists + created of that class will not contain this property. Existing property + lists containing this property are not affected. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Punregister(hid_t pclass_id, const char *name) +{ + H5P_genclass_t *pclass; /* Property list class to modify */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Punregister, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_CLS != H5I_get_type(pclass_id) || NULL == (pclass = H5I_object(pclass_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid property name"); + + /* Remove the property list from class */ + if ((ret_value=H5P_unregister(pclass,name))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "unable to remove property from class"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Punregister() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_close_list + PURPOSE + Internal routine to close a property list. + USAGE + herr_t H5P_close_list(plist) + H5P_genplist_t *plist; IN: Property list to close + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Closes a property list. If a 'close' callback exists for the property + list class, it is called before the property list is destroyed. If 'close' + callbacks exist for any individual properties in the property list, they are + called after the class 'close' callback. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The property list class 'close' callback routine is not called from + here, it must have been check for and called properly prior to this routine + being called + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5P_close_list(H5P_genplist_t *plist) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_close_list, FAIL); + + assert(plist); + + /* Decrement parent class's dependant property list value! */ + if(H5P_access_class(plist->pclass,H5P_MOD_DEC_LST)<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "Can't decrement class ref count"); + + /* Make calls to any property close callbacks which exist */ + H5P_free_all_prop(plist->props,plist->pclass->hashsize); + + /* Destroy property list object */ + H5MM_xfree(plist); + +done: + FUNC_LEAVE (ret_value); +} /* H5P_close_list() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pclose_list + PURPOSE + Routine to close a property list. + USAGE + herr_t H5Pclose_list(plist_id) + hid_t plist_id; IN: Property list to close + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Closes a property list. If a 'close' callback exists for the property + list class, it is called before the property list is destroyed. If 'close' + callbacks exist for any individual properties in the property list, they are + called after the class 'close' callback. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Pclose_list(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list created */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Pclose_list, FAIL); + + /* Check arguments. */ + if (H5I_GENPROP_LST != H5I_get_type(plist_id) || NULL == (plist = H5I_remove(plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); + + /* Make call to property list class close callback, if needed */ + if(plist->class_init!=0 && plist->pclass->close_func!=NULL) { + /* Call user's "close" callback function, ignoring return value */ + (plist->pclass->close_func)(plist_id,plist->pclass->close_data); + } /* end if */ + + /* Close the property list */ + if (H5P_close_list(plist) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close"); + +done: + FUNC_LEAVE (ret_value); +} /* H5Pclose_list() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_close_class + PURPOSE + Internal routine to close a property list class. + USAGE + herr_t H5P_create_class(class) + H5P_genclass_t *class; IN: Property list class to close + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Releases memory and de-attach a class from the property list class hierarchy. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_close_class(H5P_genclass_t *class) +{ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5P_close_class, FAIL); + + assert(class); + + /* Decrement parent class's dependant property class value! */ + if(H5P_access_class(class->parent,H5P_MOD_DEC_CLS)<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't decrement class ref count"); + + /* Mark class as deleted */ + class->deleted=1; + + /* Check dependancies on this class, deleting it if allowed */ + if(H5P_access_class(class,H5P_MOD_CHECK)<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, NULL,"Can't check class ref count"); + + /* Set return value */ + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5P_close_class() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Pclose_class + PURPOSE + Close a property list class. + USAGE + herr_t H5Pclose_class(cls_id) + hid_t cls_id; IN: Property list class ID to class + + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Releases memory and de-attach a class from the property list class hierarchy. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5Pclose_class(hid_t cls_id) +{ + H5P_genclass_t *pclass; /* Property list class created */ + hid_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER(H5Pclose_class, FAIL); + + /* Check arguments */ + if (H5I_GENPROP_CLS != H5I_get_type(cls_id) || NULL == (pclass = H5I_remove(cls_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class"); + + /* Delete the property list class */ + if (H5P_close_class(pclass) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close"); + +done: + FUNC_LEAVE(ret_value); +} /* H5Pclose_class() */ + |