From 2c8c5f96924b1e143d6047b802eda1aed9003d1c Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 25 Jul 2000 12:35:17 -0500 Subject: [svn-r2444] Checkpoint the Generic Property implementation. It's not active yet, but it's close. This shouldn't interfere with other development work. (I think.. :-) --- src/H5.c | 12 +- src/H5B.c | 2 +- src/H5D.c | 27 + src/H5Dprivate.h | 1 + src/H5F.c | 10 +- src/H5Iprivate.h | 2 + src/H5Ipublic.h | 10 +- src/H5P.c | 2772 +++++++++++++++++++++++++++++++++++++++++++++++------- src/H5Pprivate.h | 81 ++ src/H5Ppublic.h | 65 +- 10 files changed, 2642 insertions(+), 340 deletions(-) diff --git a/src/H5.c b/src/H5.c index c7fab81..d13bd10 100644 --- a/src/H5.c +++ b/src/H5.c @@ -19,6 +19,7 @@ static char RcsId[] = "@(#)$Revision$"; /* private headers */ #include /*library */ #include /*B-link trees */ +#include /*datasets */ #include /*error handling */ #include /*file driver */ #include /*Free Lists */ @@ -110,8 +111,11 @@ H5_init_library(void) /* * Initialize interfaces that might not be able to initialize themselves - * soon enough. The file interface must be initialized because calling - * H5Pcreate() might require the H5F_access_dflt to be initialized. + * soon enough. The file & dataset interfaces must be initialized because + * calling H5Pcreate() might require the file/dataset property classes to be + * initialized. The property lists are be initialized during the H5F/H5D + * init calls (because they call H5P functions, which initialize the H5P + * API, before using the properties). */ if (H5F_init()<0) { HRETURN_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, @@ -121,6 +125,10 @@ H5_init_library(void) HRETURN_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize type interface"); } + if (H5D_init()<0) { + HRETURN_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, + "unable to initialize file interface"); + } /* Debugging? */ H5_debug_mask("-all"); diff --git a/src/H5B.c b/src/H5B.c index d76b29b..8801bb1 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -95,7 +95,7 @@ #include /*Free Lists */ #include /*file memory management */ #include /*core memory management */ -#include /*property lists */ +#include /*property lists */ #include /*for H5FD_mpio_tas_allsame() */ diff --git a/src/H5D.c b/src/H5D.c index 285fddd..f305d56 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -102,6 +102,31 @@ H5FL_BLK_DEFINE_STATIC(vlen_vl_buf); H5FL_BLK_DEFINE_STATIC(vlen_fl_buf); +/*------------------------------------------------------------------------- + * Function: H5D_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 +H5D_init(void) +{ + FUNC_ENTER(H5D_init, FAIL); + /* FUNC_ENTER() does all the work */ + FUNC_LEAVE(SUCCEED); +} + + /*-------------------------------------------------------------------------- NAME H5D_init_interface -- Initialize interface-specific information @@ -125,6 +150,8 @@ H5D_init_interface(void) HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize interface"); } + +/* Register the default dataset creation & data xfer properties */ FUNC_LEAVE(SUCCEED); } diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 7fabb66..4fc441e 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -55,6 +55,7 @@ typedef struct H5D_t H5D_t; __DLLVAR__ const H5D_create_t H5D_create_dflt; /* Functions defined in H5D.c */ +__DLL__ herr_t H5D_init(void); __DLL__ H5D_t *H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, const H5S_t *space, const H5D_create_t *create_parms); diff --git a/src/H5F.c b/src/H5F.c index 0fea13c..b7cecfb 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -203,14 +203,14 @@ H5F_init_interface(void) * which are pending completion because there are object headers still * open within the file. */ - if (H5I_init_group(H5I_FILE, H5I_FILEID_HASHSIZE, 0, - (H5I_free_t)H5F_close)<0 || - H5I_init_group(H5I_FILE_CLOSING, H5I_FILEID_HASHSIZE, 0, - (H5I_free_t)H5F_close)<0) { - HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, + if (H5I_init_group(H5I_FILE, H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<0 || + H5I_init_group(H5I_FILE_CLOSING, H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<0) { + HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface"); } +/* Register the default file creation & access properties */ + /* Register predefined file drivers */ H5E_BEGIN_TRY { if ((status=H5FD_SEC2)<0) goto end_registration; diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index a142a9e..3c33fa2 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -38,6 +38,8 @@ #define H5I_RAGGED_HASHSIZE 64 #define H5I_REFID_HASHSIZE 64 #define H5I_VFL_HASHSIZE 64 +#define H5I_GENPROPCLS_HASHSIZE 64 +#define H5I_GENPROPOBJ_HASHSIZE 128 /* * Function for freeing objects. This function will be called with an object diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index 8eebf53..6afb391 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -30,7 +30,7 @@ typedef enum { H5I_BADID = (-1), /*invalid Group */ H5I_FILE = 1, /*group ID for File objects */ H5I_FILE_CLOSING, /*files pending close due to open objhdrs */ - H5I_TEMPLATE_0, /*group ID for Template objects */ + H5I_TEMPLATE_0, /*group ID for Template objects */ H5I_TEMPLATE_1, /*group ID for Template objects */ H5I_TEMPLATE_2, /*group ID for Template objects */ H5I_TEMPLATE_3, /*group ID for Template objects */ @@ -39,17 +39,19 @@ typedef enum { H5I_TEMPLATE_6, /*group ID for Template objects */ H5I_TEMPLATE_7, /*group ID for Template objects */ #ifndef NDEBUG - H5I_TEMPLATE_MAX, /*not really a group ID */ + H5I_TEMPLATE_MAX, /*not really a group ID */ #endif H5I_GROUP, /*group ID for Group objects */ H5I_DATATYPE, /*group ID for Datatype objects */ H5I_DATASPACE, /*group ID for Dataspace objects */ H5I_DATASET, /*group ID for Dataset objects */ H5I_ATTR, /*group ID for Attribute objects */ - H5I_TEMPBUF, /*group ID for Temporary buffer objects */ + H5I_TEMPBUF, /*group ID for Temporary buffer objects */ H5I_RAGGED, /*group ID for Ragged array objects */ H5I_REFERENCE, /*group ID for Reference objects */ - H5I_VFL, /*group ID for virtual file layer */ + H5I_VFL, /*group ID for virtual file layer */ + H5I_GENPROP_CLS, /*group ID for generic property list classes */ + H5I_GENPROP_LST, /*group ID for generic property lists */ H5I_NGROUPS /*number of valid groups, MUST BE LAST! */ } H5I_type_t; diff --git a/src/H5P.c b/src/H5P.c index ee8a037..3189b51 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -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= 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<=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; ilayout = 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; ichunk_ndims && ichunk_size[i]; - } + + for (i=0; ichunk_ndims && ichunk_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; idxefl.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; idxefl.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; ipline.filter[idx].cd_nelmts && i<*cd_nelmts; i++) { - cd_values[i] = plist->pline.filter[idx].cd_values[i]; - } + for (i=0; ipline.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; unext; + + /* 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 && modclasses++; + 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; uhashsize; 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() */ + diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 0e66841..4f5d16f 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -23,6 +23,65 @@ #include #include +/* Define enum for modifications to class */ +typedef enum { + H5P_MOD_ERR=(-1), /* Indicate an error */ + H5P_MOD_INC_CLS, /* Increment the dependant class count*/ + H5P_MOD_DEC_CLS, /* Decrement the dependant class count*/ + H5P_MOD_INC_LST, /* Increment the dependant list count*/ + H5P_MOD_DEC_LST, /* Decrement the dependant list count*/ + H5P_MOD_CHECK, /* Just check about deleting the class */ + H5P_MOD_MAX /* Upper limit on class modifications */ +} H5P_class_mod_t; + +/* Define structure to hold property information */ +typedef struct H5P_genprop_tag { + /* Values for this property */ + uintn xor; /* XOR'ed version of the name, for faster comparisons */ + char *name; /* Name of property */ + size_t size; /* Size of property value */ + void *value; /* Pointer to property value */ + + /* Callback function pointers & info */ + H5P_prp_create_func_t create; /* Function to call when a property is created */ + void *def_value; /* Pointer to default value to pass along to create callback */ + H5P_prp_set_func_t set; /* Function to call when a property value is set */ + H5P_prp_get_func_t get; /* Function to call when a property value is retrieved */ + H5P_prp_close_func_t close; /* Function to call when a property is closed */ + + struct H5P_genprop_tag *next; /* Pointer to the next property in this list */ +} H5P_genprop_t; + +/* Define structure to hold class information */ +typedef struct H5P_genclass_tag { + struct H5P_genclass_tag *parent; /* Pointer to parent class */ + char *name; /* Name of property list class */ + uintn nprops; /* Number of properties in class */ + uintn hashsize; /* Hash table size */ + uintn plists; /* Number of property lists that have been created since the last modification to the class */ + uintn classes; /* Number of classes that have been derived since the last modification to the class */ + uintn internal:1; /* Whether this class is internal to the library or not */ + uintn deleted:1; /* Whether this class has been deleted and is waiting for dependent classes & proplists to close */ + + /* Callback function pointers & info */ + H5P_cls_create_func_t create_func; /* Function to call when a property list is created */ + void *create_data; /* Pointer to user data to pass along to create callback */ + H5P_cls_close_func_t close_func; /* Function to call when a property list is closed */ + void *close_data; /* Pointer to user data to pass along to close callback */ + + H5P_genprop_t *props[1]; /* Hash table of pointers to properties in the class */ +} H5P_genclass_t; + +/* Define structure to hold property list information */ +typedef struct H5P_genplist_tag { + H5P_genclass_t *pclass; /* Pointer to class info */ + uintn nprops; /* Number of properties in class */ + uintn class_init:1; /* Whether the class initialization callback finished successfully */ + + /* Hash size for a property list is same as class */ + H5P_genprop_t *props[1]; /* Hash table of pointers to properties in the list */ +} H5P_genplist_t; + /* Master property list structure */ typedef struct { /* Union of all the different kinds of property lists */ @@ -36,6 +95,28 @@ typedef struct { H5P_class_t class; /* Property list class */ } H5P_t; +/* Private functions, not part of the publicly documented API */ +__DLL__ 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); +__DLL__ H5P_genplist_t *H5P_create_list(H5P_genclass_t *class); +__DLL__ 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); +__DLL__ herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, + void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, + H5P_prp_close_func_t prp_close); +__DLL__ herr_t H5P_set(H5P_genplist_t *plist, const char *name, void *value); +__DLL__ herr_t H5P_exist(H5P_genplist_t *plist, const char *name); +__DLL__ herr_t H5P_get_size(H5P_genplist_t *plist, const char *name); +__DLL__ herr_t H5P_get(H5P_genplist_t *plist, const char *name, void *value); +__DLL__ herr_t H5P_remove(H5P_genplist_t *plist, const char *name); +__DLL__ herr_t H5P_unregister(H5P_genclass_t *pclass, const char *name); +__DLL__ herr_t H5P_close_list(H5P_genplist_t *plist); +__DLL__ herr_t H5P_close_class(H5P_genclass_t *class); +__DLL__ herr_t H5P_init(void); __DLL__ hid_t H5P_create(H5P_class_t type, H5P_t *plist); __DLL__ void *H5P_copy(H5P_class_t type, const void *src); __DLL__ herr_t H5P_close(void *plist); diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 36731a6..b84ea14 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -29,25 +29,76 @@ /* Property list classes */ typedef enum H5P_class_t { - H5P_NO_CLASS = -1, /*error return value */ - H5P_FILE_CREATE = 0, /*file creation properties */ - H5P_FILE_ACCESS = 1, /*file access properties */ - H5P_DATASET_CREATE = 2, /*dataset creation properties */ - H5P_DATA_XFER = 3, /*data transfer properties */ - H5P_MOUNT = 4, /*file mounting properties */ + H5P_NO_CLASS = -1, /*error return value */ + H5P_FILE_CREATE = 0, /*file creation properties */ + H5P_FILE_ACCESS = 1, /*file access properties */ + H5P_DATASET_CREATE = 2, /*dataset creation properties */ + H5P_DATA_XFER = 3, /*data transfer properties */ + H5P_MOUNT = 4, /*file mounting properties */ - H5P_NCLASSES = 5 /*this must be last! */ + H5P_NCLASSES = 5 /*this must be last! */ } H5P_class_t; /* Alias for the previous H5P_DATASER_XFER property list */ /* This should eventually be publicly decommisioned - 10/6/99 - QAK */ #define H5P_DATASET_XFER H5P_DATA_XFER +/* Define property list class callback function pointer types */ +typedef herr_t (*H5P_cls_create_func_t)(hid_t prop_id, void *create_data); +typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data); + +/* Define property list callback function pointer types */ +typedef herr_t (*H5P_prp_create_func_t)(const char *name, void **def_value); +typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name, void **value); +typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name, void *value); +typedef herr_t (*H5P_prp_close_func_t)(const char *name, void *value); + #ifdef __cplusplus extern "C" { #endif +/* + * The library created property list classes + */ +#define H5P_NO_CLASS_NEW (H5open(), H5P_NO_CLASS_g) +#define H5P_NO_CLASS_HASH_SIZE 0 +#define H5P_FILE_CREATE_NEW (H5open(), H5P_FILE_CREATE_g) +#define H5P_FILE_CREATE_HASH_SIZE 17 +#define H5P_FILE_ACCESS_NEW (H5open(), H5P_FILE_ACCESS_g) +#define H5P_FILE_ACCESS_HASH_SIZE 17 +#define H5P_DATASET_CREATE_NEW (H5open(), H5P_DATASET_CREATE_g) +#define H5P_DATASET_CREATE_HASH_SIZE 17 +#define H5P_DATA_XFER_NEW (H5open(), H5P_DATA_XFER_g) +#define H5P_DATA_XFER_HASH_SIZE 17 +#define H5P_MOUNT_NEW (H5open(), H5P_MOUNT_g) +#define H5P_MOUNT_HASH_SIZE 17 +__DLLVAR__ hid_t H5P_NO_CLASS_g; +__DLLVAR__ hid_t H5P_FILE_CREATE_g; +__DLLVAR__ hid_t H5P_FILE_ACCESS_g; +__DLLVAR__ hid_t H5P_DATASET_CREATE_g; +__DLLVAR__ hid_t H5P_DATA_XFER_g; +__DLLVAR__ hid_t H5P_MOUNT_g; + /* Public functions */ +__DLL__ 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); +__DLL__ hid_t H5Pcreate_list(hid_t cls_id); +__DLL__ herr_t H5Pregister(hid_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); +__DLL__ 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); +__DLL__ herr_t H5Pset(hid_t plist_id, const char *name, void *value); +__DLL__ herr_t H5Pexist(hid_t plist_id, const char *name); +__DLL__ herr_t H5Pget_size(hid_t plist_id, const char *name); +__DLL__ herr_t H5Pget(hid_t plist_id, const char *name, void * value); +__DLL__ herr_t H5Premove(hid_t plist_id, const char *name); +__DLL__ herr_t H5Punregister(hid_t pclass_id, const char *name); +__DLL__ herr_t H5Pclose_list(hid_t plist_id); +__DLL__ herr_t H5Pclose_class(hid_t plist_id); __DLL__ hid_t H5Pcreate(H5P_class_t type); __DLL__ herr_t H5Pclose(hid_t plist_id); __DLL__ hid_t H5Pcopy(hid_t plist_id); -- cgit v0.12