summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2004-06-18 16:56:04 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2004-06-18 16:56:04 (GMT)
commitf249eed71d4b646bc57a43f28e32f3c2d9d71050 (patch)
tree831e79372ff27e582d5a1022e189a71d192256eb
parenta83233a2c9f1fff24cffe02d4fa3fdaab3f92ff1 (diff)
downloadhdf5-f249eed71d4b646bc57a43f28e32f3c2d9d71050.zip
hdf5-f249eed71d4b646bc57a43f28e32f3c2d9d71050.tar.gz
hdf5-f249eed71d4b646bc57a43f28e32f3c2d9d71050.tar.bz2
[svn-r8707] Changed the way HDF5 handles hid_t's and added API functions to allow users to register IDs and ID types at runtime.
-rw-r--r--src/H5.c6
-rw-r--r--src/H5A.c6
-rw-r--r--src/H5D.c6
-rw-r--r--src/H5E.c18
-rw-r--r--src/H5F.c10
-rw-r--r--src/H5FD.c6
-rw-r--r--src/H5G.c8
-rw-r--r--src/H5I.c1258
-rw-r--r--src/H5Ipkg.h20
-rw-r--r--src/H5Iprivate.h34
-rw-r--r--src/H5Ipublic.h63
-rw-r--r--src/H5P.c12
-rw-r--r--src/H5R.c6
-rw-r--r--src/H5S.c6
-rw-r--r--src/H5T.c4
-rw-r--r--test/Makefile.in5
-rw-r--r--test/testhdf5.c1
-rw-r--r--test/testhdf5.h1
-rw-r--r--test/tid.c344
19 files changed, 1406 insertions, 408 deletions
diff --git a/src/H5.c b/src/H5.c
index 806d156..87f408a 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -2090,7 +2090,7 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
} else if (obj<0) {
fprintf (out, "FAIL");
} else {
- switch (H5I_GRP(obj)) { /* Use internal H5I macro instead of function call */
+ switch (H5I_TYPE(obj)) { /* Use internal H5I macro instead of function call */
case H5I_BADID:
fprintf (out, "%ld (error)", (long)obj);
break;
@@ -2335,8 +2335,8 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
case H5I_ERROR_STACK:
fprintf (out, "H5I_ERROR_STACK");
break;
- case H5I_NGROUPS:
- fprintf (out, "H5I_NGROUPS");
+ case H5I_NTYPES:
+ fprintf (out, "H5I_NTYPES");
break;
default:
fprintf (out, "%ld", (long)id_type);
diff --git a/src/H5A.c b/src/H5A.c
index 5f5b7195..113e2a6 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -68,7 +68,7 @@ H5A_init_interface(void)
/*
* Create attribute group.
*/
- if (H5I_init_group(H5I_ATTR, H5I_ATTRID_HASHSIZE, H5A_RESERVED_ATOMS, (H5I_free_t)H5A_close)<0)
+ if (H5I_register_type(H5I_ATTR, H5I_ATTRID_HASHSIZE, H5A_RESERVED_ATOMS, (H5I_free_t)H5A_close)<0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to initialize interface")
done:
@@ -101,9 +101,9 @@ H5A_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_ATTR))) {
- H5I_clear_group(H5I_ATTR, FALSE);
+ H5I_clear_type(H5I_ATTR, FALSE);
} else {
- H5I_destroy_group(H5I_ATTR);
+ H5I_dec_type_ref(H5I_ATTR);
interface_initialize_g = 0;
n = 1;
}
diff --git a/src/H5D.c b/src/H5D.c
index 65b0879..c808faa 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -202,7 +202,7 @@ H5D_init_interface(void)
FUNC_ENTER_NOAPI_NOINIT(H5D_init_interface)
/* Initialize the atom group for the dataset IDs */
- if (H5I_init_group(H5I_DATASET, H5I_DATASETID_HASHSIZE, H5D_RESERVED_ATOMS, (H5I_free_t)H5D_close)<0)
+ if (H5I_register_type(H5I_DATASET, H5I_DATASETID_HASHSIZE, H5D_RESERVED_ATOMS, (H5I_free_t)H5D_close)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize interface")
/* =========Dataset Transfer Property Class Initialization========= */
@@ -442,9 +442,9 @@ H5D_term_interface(void)
*
* QAK - 5/13/03
*/
- H5I_clear_group(H5I_DATASET, TRUE);
+ H5I_clear_type(H5I_DATASET, TRUE);
} else {
- H5I_destroy_group(H5I_DATASET);
+ H5I_dec_type_ref(H5I_DATASET);
interface_initialize_g = 0;
n = 1; /*H5I*/
}
diff --git a/src/H5E.c b/src/H5E.c
index 9678afc..0862e89 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -145,15 +145,15 @@ H5E_init_interface(void)
FUNC_ENTER_NOAPI_NOINIT(H5E_init_interface)
/* Initialize the atom group for the error class IDs */
- if(H5I_init_group(H5I_ERROR_CLASS, H5I_ERRCLS_HASHSIZE, H5E_RESERVED_ATOMS,
+ if(H5I_register_type(H5I_ERROR_CLASS, H5I_ERRCLS_HASHSIZE, H5E_RESERVED_ATOMS,
(H5I_free_t)H5E_unregister_class)<0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
/* Initialize the atom group for the major error IDs */
- if(H5I_init_group(H5I_ERROR_MSG, H5I_ERRMSG_HASHSIZE, H5E_RESERVED_ATOMS,
+ if(H5I_register_type(H5I_ERROR_MSG, H5I_ERRMSG_HASHSIZE, H5E_RESERVED_ATOMS,
(H5I_free_t)H5E_close_msg)<0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
/* Initialize the atom group for the error stacks */
- if(H5I_init_group(H5I_ERROR_STACK, H5I_ERRSTK_HASHSIZE, H5E_RESERVED_ATOMS,
+ if(H5I_register_type(H5I_ERROR_STACK, H5I_ERRSTK_HASHSIZE, H5E_RESERVED_ATOMS,
(H5I_free_t)H5E_close_stack)<0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
@@ -213,11 +213,11 @@ H5E_term_interface(void)
if(n>0) {
/* Clear any outstanding error stacks */
if (nstk>0)
- H5I_clear_group(H5I_ERROR_STACK, FALSE);
+ H5I_clear_type(H5I_ERROR_STACK, FALSE);
/* Clear all the error classes */
if (ncls>0) {
- H5I_clear_group(H5I_ERROR_CLASS, FALSE);
+ H5I_clear_type(H5I_ERROR_CLASS, FALSE);
/* Reset the HDF5 error class, if its been closed */
if(H5I_nmembers(H5I_ERROR_CLASS)==0)
@@ -226,7 +226,7 @@ H5E_term_interface(void)
/* Clear all the error messages */
if (nmsg>0) {
- H5I_clear_group(H5I_ERROR_MSG, FALSE);
+ H5I_clear_type(H5I_ERROR_MSG, FALSE);
/* Reset the HDF5 error messages, if they've been closed */
if(H5I_nmembers(H5I_ERROR_MSG)==0) {
@@ -237,9 +237,9 @@ H5E_term_interface(void)
} else {
/* Destroy the error class, message, and stack id groups */
- H5I_destroy_group(H5I_ERROR_STACK);
- H5I_destroy_group(H5I_ERROR_CLASS);
- H5I_destroy_group(H5I_ERROR_MSG);
+ H5I_dec_type_ref(H5I_ERROR_STACK);
+ H5I_dec_type_ref(H5I_ERROR_CLASS);
+ H5I_dec_type_ref(H5I_ERROR_MSG);
/* Mark closed */
interface_initialize_g = 0;
diff --git a/src/H5F.c b/src/H5F.c
index 456a799..8091920 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -232,8 +232,8 @@ 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)
+ if (H5I_register_type(H5I_FILE, H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<0 ||
+ H5I_register_type(H5I_FILE_CLOSING, H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<0)
HGOTO_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface")
/* ========== File Creation Property Class Initialization ============*/
@@ -463,10 +463,10 @@ H5F_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_FILE))) {
- H5I_clear_group(H5I_FILE, FALSE);
+ H5I_clear_type(H5I_FILE, FALSE);
} else if (0==(n=H5I_nmembers(H5I_FILE_CLOSING))) {
- H5I_destroy_group(H5I_FILE);
- H5I_destroy_group(H5I_FILE_CLOSING);
+ H5I_dec_type_ref(H5I_FILE);
+ H5I_dec_type_ref(H5I_FILE_CLOSING);
interface_initialize_g = 0;
n = 1; /*H5I*/
}
diff --git a/src/H5FD.c b/src/H5FD.c
index 306bfbc..95b825a 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -124,7 +124,7 @@ H5FD_init_interface(void)
FUNC_ENTER_NOAPI_NOINIT(H5FD_init_interface)
- if (H5I_init_group(H5I_VFL, H5I_VFL_HASHSIZE, 0, (H5I_free_t)H5FD_free_cls)<0)
+ if (H5I_register_type(H5I_VFL, H5I_VFL_HASHSIZE, 0, (H5I_free_t)H5FD_free_cls)<0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface")
/* Reset the file serial numbers */
@@ -164,7 +164,7 @@ H5FD_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_VFL))) {
- H5I_clear_group(H5I_VFL, FALSE);
+ H5I_clear_type(H5I_VFL, FALSE);
/* Reset the VFL drivers, if they've been closed */
if(H5I_nmembers(H5I_VFL)==0) {
@@ -192,7 +192,7 @@ H5FD_term_interface(void)
#endif
} /* end if */
} else {
- H5I_destroy_group(H5I_VFL);
+ H5I_dec_type_ref(H5I_VFL);
interface_initialize_g = 0;
n = 1; /*H5I*/
}
diff --git a/src/H5G.c b/src/H5G.c
index f465de6..4c6fd16 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -954,7 +954,7 @@ H5G_init_interface(void)
FUNC_ENTER_NOAPI_NOINIT(H5G_init_interface);
/* Initialize the atom group for the group IDs */
- if (H5I_init_group(H5I_GROUP, H5I_GROUPID_HASHSIZE, H5G_RESERVED_ATOMS,
+ if (H5I_register_type(H5I_GROUP, H5I_GROUPID_HASHSIZE, H5G_RESERVED_ATOMS,
(H5I_free_t)H5G_close) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface");
@@ -1000,7 +1000,7 @@ H5G_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_GROUP))) {
- H5I_clear_group(H5I_GROUP, FALSE);
+ H5I_clear_type(H5I_GROUP, FALSE);
} else {
/* Empty the object type table */
for (i=0; i<H5G_ntypes_g; i++)
@@ -1009,7 +1009,7 @@ H5G_term_interface(void)
H5G_type_g = H5MM_xfree(H5G_type_g);
/* Destroy the group object id group */
- H5I_destroy_group(H5I_GROUP);
+ H5I_dec_type_ref(H5I_GROUP);
/* Free the global component buffer */
H5G_comp_g = H5MM_xfree(H5G_comp_g);
@@ -2277,7 +2277,7 @@ H5G_loc (hid_t loc_id)
case H5I_REFERENCE:
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of reference");
- case H5I_NGROUPS:
+ case H5I_NTYPES:
case H5I_BADID:
case H5I_FILE_CLOSING:
case H5I_VFL:
diff --git a/src/H5I.c b/src/H5I.c
index ecf3169..bf378ee 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -16,13 +16,14 @@
* FILE: H5I.c - Internal storage routines for handling "IDs"
*
* REMARKS: ID's which allow objects (void *'s currently) to be bundled
- * into "groups" for more general storage.
+ * into "types" for more general storage.
*
- * DESIGN: The groups are stored in an array of pointers to store each
- * group in an element. Each "group" node contains a link to a
- * hash table to manage the IDs in each group. The allowed
- * "groups" are stored in an enum (called group_t) in
- * H5Ipublic.h.
+ * DESIGN: The types are stored in an array of pointers to store each
+ * type in an element. Each "type" node contains a link to a
+ * hash table to manage the IDs in each type. Allowed types are
+ * values within the range 1 to MAX_NUM_TYPES and are given out
+ * at run-time. Types used by the library are stored in global
+ * variables defined in H5Ipublic.h.
*
* AUTHOR: Quincey Koziol
*
@@ -30,6 +31,7 @@
* 1/3/96 - Starting writing specs & coding prototype
* 1/7/96 - Finished coding prototype
* 6/10/97 - Moved into HDF5 library
+ * 5/18/04 - Expanded to allow registration of new types at run-time
*/
#define H5I_PACKAGE /*suppress error about including H5Ipkg */
@@ -80,8 +82,8 @@ static int interface_initialize_g = 0;
# define H5I_LOC(a,s) (((hid_t)(a)&ID_MASK)%(s))
#endif
-/* Combine a Group number and an atom index into an atom */
-#define H5I_MAKE(g,i) ((((hid_t)(g)&GROUP_MASK)<<ID_BITS)| \
+/* Combine a Type number and an atom index into an atom */
+#define H5I_MAKE(g,i) ((((hid_t)(g)&TYPE_MASK)<<ID_BITS)| \
((hid_t)(i)&ID_MASK))
/* Local typedefs */
@@ -94,9 +96,9 @@ typedef struct H5I_id_info_t {
struct H5I_id_info_t *next; /* link to next atom (in case of hash-clash)*/
} H5I_id_info_t;
-/* ID group structure used */
+/* ID type structure used */
typedef struct {
- unsigned count; /*# of times this group has been initialized*/
+ unsigned count; /*# of times this type has been initialized*/
unsigned reserved; /*# of IDs to reserve for constant IDs */
unsigned wrapped; /*whether the id count has wrapped around */
size_t hash_size; /*sizeof the hash table to store the IDs in */
@@ -104,12 +106,21 @@ typedef struct {
unsigned nextid; /*ID to use for the next atom */
H5I_free_t free_func; /*release object method */
H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */
-} H5I_id_group_t;
+} H5I_id_type_t;
+
/*-------------------- Locally scoped variables -----------------------------*/
-/* Array of pointers to atomic groups */
-static H5I_id_group_t *H5I_id_group_list_g[H5I_NGROUPS];
+/* Array of pointers to atomic types */
+static H5I_id_type_t *H5I_id_type_list_g[MAX_NUM_TYPES];
+
+/* Variable to keep track of the number of types allocated. Its value is the */
+/* next type ID to be handed out, so it is always one greater than the number */
+/* of types. */
+/* Starts at 1 instead of 0 because it makes trace output look nicer. If more */
+/* types (or IDs within a type) are needed, adjust TYPE_BITS in H5Ipkg.h */
+/* and/or increase size of hid_t */
+static H5I_type_t H5I_next_type = (H5I_type_t) H5I_NTYPES;
/* Declare a free list to manage the H5I_id_info_t struct */
H5FL_DEFINE_STATIC(H5I_id_info_t);
@@ -120,7 +131,7 @@ static H5I_id_info_t *H5I_find_id(hid_t id);
static hid_t H5I_get_file_id(hid_t obj_id);
static int H5I_get_ref(hid_t id);
#ifdef H5I_DEBUG_OUTPUT
-static herr_t H5I_debug(H5I_type_t grp);
+static herr_t H5I_debug(H5I_type_t type);
#endif /* H5I_DEBUG_OUTPUT */
@@ -144,12 +155,6 @@ H5I_init_interface(void)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_init_interface);
- /*
- * Make certain the ID types don't overflow the number of bits allocated
- * for them in an ID.
- */
- assert(H5I_NGROUPS<=(1<<GROUP_BITS));
-
FUNC_LEAVE_NOAPI(SUCCEED);
}
@@ -159,7 +164,7 @@ H5I_init_interface(void)
*
* Purpose: Terminate the H5I interface: release all memory, reset all
* global variables to initial values. This only happens if all
- * groups have been destroyed from other interfaces.
+ * types have been destroyed from other interfaces.
*
* Return: Success: Positive if any action was taken that might
* affect some other interface; zero otherwise.
@@ -175,25 +180,25 @@ H5I_init_interface(void)
int
H5I_term_interface(void)
{
- H5I_id_group_t *grp_ptr;
- H5I_type_t grp;
+ H5I_id_type_t *type_ptr;
+ H5I_type_t type;
int n=0;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_term_interface);
if (interface_initialize_g) {
- /* How many groups are still being used? */
- for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; H5_INC_ENUM(H5I_type_t,grp)) {
- if ((grp_ptr=H5I_id_group_list_g[grp]) && grp_ptr->id_list)
+ /* How many types are still being used? */
+ for (type=(H5I_type_t)0; type<H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
+ if ((type_ptr=H5I_id_type_list_g[type]) && type_ptr->id_list)
n++;
}
- /* If no groups are used then clean up */
+ /* If no types are used then clean up */
if (0==n) {
- for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; H5_INC_ENUM(H5I_type_t,grp)) {
- grp_ptr = H5I_id_group_list_g[grp];
- H5MM_xfree(grp_ptr);
- H5I_id_group_list_g[grp] = NULL;
+ for (type=(H5I_type_t)0; type<H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) {
+ type_ptr = H5I_id_type_list_g[type];
+ H5MM_xfree(type_ptr);
+ H5I_id_type_list_g[type] = NULL;
}
}
@@ -202,31 +207,69 @@ H5I_term_interface(void)
}
FUNC_LEAVE_NOAPI(n);
}
-
-
/*-------------------------------------------------------------------------
- * Function: H5I_init_group
- *
- * Purpose: Initialize an ID group whose ID number is specified by GRP,
- * If the group has already been initialized, this routine just
- * increments the count of number of initializations and returns
- * without trying to change the size of the hash table. A
- * specific number (RESERVED) of group entries may be reserved
- * to enable "constant" values to be handed out which are valid
- * IDs in the group, but which do not map to any data structures
- * and are not allocated dynamicly later. HASH_SIZE is the
- * minimum hash table size to use for the group. FREE_FUNC is
+ * Function: H5Iregister_type
+ *
+ * Purpose: Public interface to H5I_register_type. Creates a new type
+ * of ID's to give out. A specific number (RESERVED) of type
+ * entries may be reserved to enable "constant" values to be handed
+ * out which are valid IDs in the type, but which do not map to any
+ * data structures and are not allocated dynamically later. HASH_SIZE is
+ * the minimum hash table size to use for the type. FREE_FUNC is
* called with an object pointer when the object is removed from
- * the group.
+ * the type.
*
- * Return: Success: Non-negative
+ * Return: Success: Type ID of the new type
*
- * Failure: Negative
+ * Failure: H5I_BADID
*
- * Programmer: Robb Matzke
- * Friday, February 19, 1999
+ * Programmers: Nathaniel Furrer
+ * James Laird
+ * Friday, April 30, 2004
*
* Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func)
+{
+ H5I_type_t ret_value;
+ FUNC_ENTER_API(H5Iregister_type, H5I_BADID);
+
+ /* Call H5I_register_type with a value of 0 to get a new type */
+ ret_value = H5I_register_type(0, hash_size, reserved, free_func);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_register_type
+ *
+ * Purpose: Creates a new type of ID's to give out. A specific number
+ * (RESERVED) of type entries may be reserved to enable "constant"
+ * values to be handed out which are valid IDs in the type, but
+ * which do not map to any data structures and are not allocated
+ * dynamically later. TYPE_ID is the H5I_type_t value of the type
+ * to be initialized. If this value is zero, a new type is created.
+ * If this value is one of the library types, that type is
+ * initialized or its reference count is incremented (if it is already
+ * initialized). HASH_SIZE is the minimum hash table size to
+ * use for the type. FREE_FUNC is called with an object pointer
+ * when the object is removed from the type.
+ *
+ * Return: Success: Type ID of the new type
+ * Failure: H5I_BADID
+ *
+ * Programmers: Nathaniel Furrer
+ * James Laird
+ * Friday, April 30, 2004
+ *
+ * Modifications: The initialization section of this function was formerly
+ * H5I_init_type, programmed by Robb Matzke on February 19,
+ * 1999.
+ *
* Bill Wendling, 2000-05-05
* Instead of the ugly test of whether hash_size is a power of
* two, I placed it in a macro POWER_OF_TWO which uses the fact
@@ -238,68 +281,142 @@ H5I_term_interface(void)
*
*-------------------------------------------------------------------------
*/
-int
-H5I_init_group(H5I_type_t grp, size_t hash_size, unsigned reserved,
- H5I_free_t free_func)
+
+H5I_type_t H5I_register_type(H5I_type_t type_id, size_t hash_size, unsigned reserved, H5I_free_t free_func)
{
- H5I_id_group_t *grp_ptr = NULL; /*ptr to the atomic group*/
- int ret_value = SUCCEED; /*return value */
+ H5I_type_t ret_value; /* type ID to return */
+ H5I_id_type_t *type_ptr = NULL; /*ptr to the atomic type*/
+ int i;
+ int done;
+
+ FUNC_ENTER_NOAPI(H5I_register_type, H5I_BADID);
- FUNC_ENTER_NOAPI(H5I_init_group, FAIL);
+ /* Check that type_id is either a library type or zero */
+ if(type_id < 0 || type_id >= H5I_NTYPES)
+ {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid type ID");
+ }
+
+ if(type_id == 0) /* Generate a new H5I_type_t value */
+ {
+ /* Increment the number of types*/
+ if (H5I_next_type < MAX_NUM_TYPES)
+ {
+ ret_value = H5I_next_type;
+ H5I_next_type++;
+ }
+ else
+ {
+ done = 0;
+ /* Look for a free type to give out */
+ for(i = H5I_NTYPES; i < MAX_NUM_TYPES && done==0; i++)
+ {
+ if(H5I_id_type_list_g[i] == NULL)
+ {
+ /* Found a free type ID */
+ ret_value = i;
+ done = 1;
+ }
+ }
+
+ /* Verify that we found a type to give out */
+ if(done == 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded.");
+ }
+ }
+ else /* type_id is a library type; use this value. */
+ {
+ ret_value = type_id;
+ }
+
+ /* Initialize the type */
/* Check arguments */
- if ((grp <= H5I_BADID || grp >= H5I_NGROUPS) && hash_size > 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
#ifdef HASH_SIZE_POWER_2
if (!POWER_OF_TWO(hash_size) || hash_size == 1)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid hash size");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_BADID, "invalid hash size");
#endif /* HASH_SIZE_POWER_2 */
- if (H5I_id_group_list_g[grp] == NULL) {
- /* Allocate the group information for new group */
- if (NULL==(grp_ptr = H5MM_calloc(sizeof(H5I_id_group_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- H5I_id_group_list_g[grp] = grp_ptr;
+ if (H5I_id_type_list_g[ret_value] == NULL) {
+ /* Allocate the type information for new type */
+ if (NULL==(type_ptr = H5MM_calloc(sizeof(H5I_id_type_t))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed");
+ H5I_id_type_list_g[ret_value] = type_ptr;
} else {
- /* Get the pointer to the existing group */
- grp_ptr = H5I_id_group_list_g[grp];
+ /* Get the pointer to the existing type */
+ type_ptr = H5I_id_type_list_g[ret_value];
}
- if (grp_ptr->count == 0) {
- /* Initialize the ID group structure for new groups */
- grp_ptr->hash_size = hash_size;
- grp_ptr->reserved = reserved;
- grp_ptr->wrapped = 0;
- grp_ptr->ids = 0;
- grp_ptr->nextid = reserved;
- grp_ptr->free_func = free_func;
- grp_ptr->id_list = H5MM_calloc(hash_size*sizeof(H5I_id_info_t *));
- if (NULL==grp_ptr->id_list)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if (type_ptr->count == 0) {
+ /* Initialize the ID type structure for new types */
+ type_ptr->hash_size = hash_size;
+ type_ptr->reserved = reserved;
+ type_ptr->wrapped = 0;
+ type_ptr->ids = 0;
+ type_ptr->nextid = reserved;
+ type_ptr->free_func = free_func;
+ type_ptr->id_list = H5MM_calloc(hash_size*sizeof(H5I_id_info_t *));
+ if (NULL==type_ptr->id_list)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "memory allocation failed");
}
-
- /* Increment the count of the times this group has been initialized */
- grp_ptr->count++;
-done:
- if (ret_value<0) {
- /* Error condition cleanup */
- if (grp_ptr != NULL) {
- H5MM_xfree(grp_ptr->id_list);
- H5MM_xfree(grp_ptr);
+ /* Increment the count of the times this type has been initialized */
+ type_ptr->count++;
+
+ done:
+ if(ret_value == H5I_BADID) /* Clean up on error */
+ {
+ if (type_ptr != NULL)
+ {
+ H5MM_xfree(type_ptr->id_list);
+ H5MM_xfree(type_ptr);
+ }
}
- }
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value);
}
-
+/*-------------------------------------------------------------------------
+ * Function: H5Inmembers
+ *
+ * Purpose: Returns the number of members in a type. Public interface to
+ * H5I_nmembers.
+ *
+ * Return: Success: Number of members; zero if the type is empty
+ * or has been deleted.
+ *
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int H5Inmembers(H5I_type_t type)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Inmembers, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_nmembers(type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
/*-------------------------------------------------------------------------
* Function: H5I_nmembers
*
- * Purpose: Returns the number of members in a group.
+ * Purpose: Returns the number of members in a type.
*
- * Return: Success: Number of members; zero if the group is empty
+ * Return: Success: Number of members; zero if the type is empty
* or has been deleted.
*
* Failure: Negative
@@ -312,9 +429,9 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5I_nmembers(H5I_type_t grp)
+H5I_nmembers(H5I_type_t type)
{
- H5I_id_group_t *grp_ptr = NULL;
+ H5I_id_type_t *type_ptr = NULL;
H5I_id_info_t *cur=NULL;
int n=0;
unsigned i;
@@ -322,13 +439,13 @@ H5I_nmembers(H5I_type_t grp)
FUNC_ENTER_NOAPI(H5I_nmembers, FAIL);
- if (grp<=H5I_BADID || grp>=H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- if (NULL==(grp_ptr=H5I_id_group_list_g[grp]) || grp_ptr->count<=0)
+ if (type<=H5I_BADID || type>=H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ if (NULL==(type_ptr=H5I_id_type_list_g[type]) || type_ptr->count<=0)
HGOTO_DONE(0);
- for (i=0; i<grp_ptr->hash_size; i++)
- for (cur=grp_ptr->id_list[i]; cur; cur=cur->next)
+ for (i=0; i<type_ptr->hash_size; i++)
+ for (cur=type_ptr->id_list[i]; cur; cur=cur->next)
n++;
/* Set return value */
@@ -338,11 +455,45 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
/*-------------------------------------------------------------------------
- * Function: H5I_clear_group
+ * Function: H5Iclear_type
*
- * Purpose: Removes all objects from the group, calling the free
+ * Purpose: Removes all objects from the type, calling the free
+ * function for each object regardless of the reference count.
+ * Public interface to H5I_clear_type.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+herr_t H5Iclear_type(H5I_type_t type, hbool_t force)
+{
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iclear_type, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_clear_type(type, force);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_clear_type
+ *
+ * Purpose: Removes all objects from the type, calling the free
* function for each object regardless of the reference count.
*
* Return: Success: Non-negative
@@ -368,9 +519,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5I_clear_group(H5I_type_t grp, hbool_t force)
+H5I_clear_type(H5I_type_t type, hbool_t force)
{
- H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */
+ H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
H5I_id_info_t *cur=NULL; /* Current node being worked with */
H5I_id_info_t *next=NULL; /* Next node in list */
H5I_id_info_t *last=NULL; /* Last node seen */
@@ -379,22 +530,22 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
unsigned delete_node; /* Flag to indicate node should be removed from linked list */
unsigned i;
- FUNC_ENTER_NOAPI(H5I_clear_group, FAIL);
+ FUNC_ENTER_NOAPI(H5I_clear_type, FAIL);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
/*
- * Call free method for all objects in group regardless of their reference
+ * Call free method for all objects in type regardless of their reference
* counts. Ignore the return value from from the free method and remove
- * object from group regardless if FORCE is non-zero.
+ * object from type regardless if FORCE is non-zero.
*/
- for (i=0; i<grp_ptr->hash_size; i++) {
- for (cur=grp_ptr->id_list[i]; cur; cur=next) {
+ for (i=0; i<type_ptr->hash_size; i++) {
+ for (cur=type_ptr->id_list[i]; cur; cur=next) {
/*
* Do nothing to the object if the reference count is larger than
* one and forcing is off.
@@ -405,12 +556,12 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
} /* end if */
/* Check for a 'free' function and call it, if it exists */
- if (grp_ptr->free_func && (grp_ptr->free_func)(cur->obj_ptr)<0) {
+ if (type_ptr->free_func && (type_ptr->free_func)(cur->obj_ptr)<0) {
if (force) {
#ifdef H5I_DEBUG
if (H5DEBUG(I)) {
- fprintf(H5DEBUG(I), "H5I: free grp=%d obj=0x%08lx "
- "failure ignored\n", (int)grp,
+ fprintf(H5DEBUG(I), "H5I: free type=%d obj=0x%08lx "
+ "failure ignored\n", (int)type,
(unsigned long)(cur->obj_ptr));
} /* end if */
#endif /*H5I_DEBUG*/
@@ -430,8 +581,8 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
/* Check if we should delete this node or not */
if(delete_node) {
- /* Decrement the number of IDs in the group */
- (grp_ptr->ids)--;
+ /* Decrement the number of IDs in the type */
+ (type_ptr->ids)--;
/* Advance to next node */
next = cur->next;
@@ -442,7 +593,7 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
/* make an H5I call, which could potentially change the */
/* order of the nodes on the list - QAK) */
last=NULL;
- tmp=grp_ptr->id_list[i];
+ tmp=type_ptr->id_list[i];
while(tmp!=cur) {
assert(tmp!=NULL);
last=tmp;
@@ -452,8 +603,8 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
/* Delete the node from the list */
if(last==NULL) {
/* Node at head of list, just advance the list head to next node */
- assert(grp_ptr->id_list[i]==cur);
- grp_ptr->id_list[i] = next;
+ assert(type_ptr->id_list[i]==cur);
+ type_ptr->id_list[i] = next;
} /* end if */
else {
/* Node in middle of list, jump over it */
@@ -475,71 +626,126 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
/*-------------------------------------------------------------------------
- * Function: H5I_destroy_group
+ * Function: H5Idestroy_type
*
- * Purpose: Decrements the reference count on an entire group of IDs.
- * If the group reference count becomes zero then the group is
- * destroyed along with all atoms in that group regardless of
- * their reference counts. Destroying IDs involves calling
- * the free-func for each ID's object and then adding the ID
- * struct to the ID free list.
+ * Purpose: Destroys a type along with all atoms in that type
+ * regardless of their reference counts. Destroying IDs
+ * involves calling the free-func for each ID's object and
+ * then adding the ID struct to the ID free list. Public
+ * interface to H5I_destroy_type.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Zero on success/Negative on failure
*
- * Programmer: Unknown
+ * Programmer: Nathaniel Furrer
+ * James Laird
*
* Modifications:
*
- * Robb Matzke, 25 Feb 1998
- * IDs are freed when a group is destroyed.
+ *-------------------------------------------------------------------------
+ */
+herr_t H5Idestroy_type(H5I_type_t type)
+{
+ herr_t ret_value;
+
+ FUNC_ENTER_API(H5Idestroy_type, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_destroy_type(type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_destroy_type
+ *
+ * Purpose: Destroys a type along with all atoms in that type
+ * regardless of their reference counts. Destroying IDs
+ * involves calling the free-func for each ID's object and
+ * then adding the ID struct to the ID free list.
+ *
+ * Return: Zero on success/Negative on failure
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ *
+ * Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5I_destroy_group(H5I_type_t grp)
+herr_t H5I_destroy_type(H5I_type_t type)
{
- H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */
- int ret_value = SUCCEED;
+ herr_t ret_value = FAIL;
+ H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
- FUNC_ENTER_NOAPI(H5I_destroy_group, FAIL);
+ FUNC_ENTER_NOAPI(H5I_destroy_type, FAIL);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
-
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
- /*
- * Decrement the number of users of the atomic group. If this is the
- * last user of the group then release all atoms from the group. The
- * free function is invoked for each atom being freed.
- */
- if (1==grp_ptr->count) {
- H5I_clear_group(grp, TRUE);
- H5E_clear(NULL); /*don't care about errors*/
- H5MM_xfree(grp_ptr->id_list);
- HDmemset (grp_ptr, 0, sizeof(*grp_ptr));
- } else {
- --(grp_ptr->count);
- }
-
- done:
- FUNC_LEAVE_NOAPI(ret_value);
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ H5I_clear_type(type, TRUE);
+ H5E_clear(NULL); /*don't care about errors*/
+ H5MM_xfree(type_ptr->id_list);
+
+ H5MM_free(type_ptr);
+ H5I_id_type_list_g[type] = NULL;
+ ret_value = 0;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iregister
+ *
+ * Purpose: Public interface to H5I_register.
+ *
+ * Return: Success: New object id.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t H5Iregister(H5I_type_t type, void *object)
+{
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iregister, H5I_INVALID_HID);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_register(type, object);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
}
-
/*-------------------------------------------------------------------------
* Function: H5I_register
*
- * Purpose: Registers an OBJECT in a GROUP and returns an ID for it.
+ * Purpose: Registers an OBJECT in a TYPE and returns an ID for it.
* This routine does _not_ check for unique-ness of the objects,
* if you register an object twice, you will get two different
* IDs for it. This routine does make certain that each ID in a
- * group is unique. IDs are created by getting a unique number
- * for the group the ID is in and incorporating the group into
+ * type is unique. IDs are created by getting a unique number
+ * for the type the ID is in and incorporating the type into
* the ID which is returned to the user.
*
* Return: Success: New object id.
@@ -553,9 +759,9 @@ H5I_destroy_group(H5I_type_t grp)
*-------------------------------------------------------------------------
*/
hid_t
-H5I_register(H5I_type_t grp, void *object)
+H5I_register(H5I_type_t type, void *object)
{
- H5I_id_group_t *grp_ptr=NULL; /*ptr to the group */
+ H5I_id_type_t *type_ptr=NULL; /*ptr to the type */
H5I_id_info_t *id_ptr=NULL; /*ptr to the new ID information */
hid_t new_id; /*new ID */
unsigned hash_loc; /*new item's hash table location*/
@@ -567,61 +773,61 @@ H5I_register(H5I_type_t grp, void *object)
FUNC_ENTER_NOAPI(H5I_register, FAIL);
/* Check arguments */
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
if ((id_ptr = H5FL_MALLOC(H5I_id_info_t)) == NULL)
HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Create the struct & it's ID */
- new_id = H5I_MAKE(grp, grp_ptr->nextid);
+ new_id = H5I_MAKE(type, type_ptr->nextid);
id_ptr->id = new_id;
id_ptr->count = 1; /*initial reference count*/
id_ptr->obj_ptr = object;
id_ptr->next = NULL;
/* hash bucket already full, prepend to front of chain */
- hash_loc = grp_ptr->nextid % (unsigned) grp_ptr->hash_size;
- if (grp_ptr->id_list[hash_loc] != NULL)
- id_ptr->next = grp_ptr->id_list[hash_loc];
+ hash_loc = type_ptr->nextid % (unsigned) type_ptr->hash_size;
+ if (type_ptr->id_list[hash_loc] != NULL)
+ id_ptr->next = type_ptr->id_list[hash_loc];
- /* Insert into the group */
- grp_ptr->id_list[hash_loc] = id_ptr;
- grp_ptr->ids++;
- grp_ptr->nextid++;
+ /* Insert into the type */
+ type_ptr->id_list[hash_loc] = id_ptr;
+ type_ptr->ids++;
+ type_ptr->nextid++;
/*
* This next section of code checks for the 'nextid' getting too large and
* wrapping around, thus necessitating checking for duplicate IDs being
* handed out.
*/
- if (grp_ptr->nextid > (unsigned)ID_MASK) {
- grp_ptr->wrapped = 1;
- grp_ptr->nextid = grp_ptr->reserved;
+ if (type_ptr->nextid > (unsigned)ID_MASK) {
+ type_ptr->wrapped = 1;
+ type_ptr->nextid = type_ptr->reserved;
}
/*
* If we've wrapped around then we need to check for duplicate id's being
* handed out.
*/
- if (grp_ptr->wrapped) {
+ if (type_ptr->wrapped) {
/*
* Make sure we check all available ID's. If we're about at the end
* of the range then wrap around and check the beginning values. If
* we check all possible values and didn't find any free ones *then*
* we can fail.
*/
- for (i=grp_ptr->reserved; i<ID_MASK; i++) {
+ for (i=type_ptr->reserved; i<ID_MASK; i++) {
/* Handle end of range by wrapping to beginning */
- if (grp_ptr->nextid>(unsigned)ID_MASK)
- grp_ptr->nextid = grp_ptr->reserved;
+ if (type_ptr->nextid>(unsigned)ID_MASK)
+ type_ptr->nextid = type_ptr->reserved;
/* new ID to check for */
- next_id = H5I_MAKE(grp, grp_ptr->nextid);
- hash_loc = H5I_LOC (grp_ptr->nextid, grp_ptr->hash_size);
- curr_id = grp_ptr->id_list[hash_loc];
+ next_id = H5I_MAKE(type, type_ptr->nextid);
+ hash_loc = H5I_LOC (type_ptr->nextid, type_ptr->hash_size);
+ curr_id = type_ptr->id_list[hash_loc];
if (curr_id == NULL)
break; /* Ha! this is not likely... */
@@ -632,12 +838,12 @@ H5I_register(H5I_type_t grp, void *object)
}
if (!curr_id)
break; /* must not have found a match */
- grp_ptr->nextid++;
+ type_ptr->nextid++;
}
if (i>=(unsigned)ID_MASK)
/* All the IDs are gone! */
- HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in group");
+ HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type");
}
ret_value = new_id;
@@ -680,12 +886,48 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
+/*-------------------------------------------------------------------------
+ * Function: H5Iobject_verify
+ *
+ * Purpose: Find an object pointer for the specified ID, verifying that
+ * its in a particular type. Public interface to
+ * H5I_object_verify.
+ *
+ * Return: Success: Non-null object pointer associated with the
+ * specified ID.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *H5Iobject_verify(hid_t id, H5I_type_t id_type)
+{
+ void * ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iobject_verify, NULL);
+
+ if( H5I_IS_LIB_TYPE( id_type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_object_verify(id, id_type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
/*-------------------------------------------------------------------------
* Function: H5I_object_verify
*
* Purpose: Find an object pointer for the specified ID, verifying that
- * its in a particular group.
+ * its in a particular type.
*
* Return: Success: Non-null object pointer associated with the
* specified ID.
@@ -707,10 +949,10 @@ H5I_object_verify(hid_t id, H5I_type_t id_type)
FUNC_ENTER_NOAPI(H5I_object_verify, NULL);
- assert(id_type>=H5I_FILE && id_type<H5I_NGROUPS);
+ assert(id_type>=1 && id_type<H5I_next_type);
- /* Verify that the group of the ID is correct & lookup the ID */
- if(id_type == H5I_GRP(id) && NULL!=(id_ptr = H5I_find_id(id))) {
+ /* Verify that the type of the ID is correct & lookup the ID */
+ if(id_type == H5I_TYPE(id) && NULL!=(id_ptr = H5I_find_id(id))) {
/* Get the object pointer to return */
ret_value = id_ptr->obj_ptr;
} /* end if */
@@ -723,12 +965,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5I_get_type
*
- * Purpose: Given an object ID return the group (type) to which it
+ * Purpose: Given an object ID return the type to which it
* belongs. The ID need not be the ID of an object which
- * currently exists because the group number (type) is encoded
+ * currently exists because the type number is encoded
* in the object ID.
*
- * Return: Success: A valid group number (type)
+ * Return: Success: A valid type number
*
* Failure: H5I_BADID, a negative value.
*
@@ -747,9 +989,9 @@ H5I_get_type(hid_t id)
FUNC_ENTER_NOAPI(H5I_get_type, H5I_BADID);
if (id>0)
- ret_value = H5I_GRP(id);
+ ret_value = H5I_TYPE(id);
- assert(ret_value>=H5I_BADID && ret_value<H5I_NGROUPS);
+ assert(ret_value>=H5I_BADID && ret_value<H5I_next_type);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -759,12 +1001,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Iget_type
*
- * Purpose: The public version of H5I_get_type(), obtains a group number
- * (type) when given an ID. The ID need not be the ID of an
- * object which currently exists because the group number is
+ * Purpose: The public version of H5I_get_type(), obtains a type number
+ * when given an ID. The ID need not be the ID of an
+ * object which currently exists because the type number is
* encoded as part of the ID.
*
- * Return: Success: Group number (type)
+ * Return: Success: Type number
*
* Failure: H5I_BADID, a negative value
*
@@ -772,7 +1014,7 @@ done:
*
* Modifications:
* Robb Matzke, 1999-08-23
- * Also fails if the ID has a valid group but no longer exists
+ * Also fails if the ID has a valid type but no longer exists
* in the ID tables.
*-------------------------------------------------------------------------
*/
@@ -786,7 +1028,7 @@ H5Iget_type(hid_t id)
ret_value = H5I_get_type(id);
- if (ret_value <= H5I_BADID || ret_value >= H5I_NGROUPS || NULL==H5I_object(id))
+ if (ret_value <= H5I_BADID || ret_value >= H5I_next_type || NULL==H5I_object(id))
HGOTO_DONE(H5I_BADID);
done:
@@ -849,47 +1091,120 @@ H5I_get_file_id(hid_t obj_id)
{
H5G_entry_t *ent;
hid_t ret_value;
+ H5I_type_t type;
FUNC_ENTER_NOAPI_NOINIT(H5I_get_file_id);
/* Get object type */
- switch(H5I_GRP(obj_id)) {
- case H5I_FILE:
- ret_value = obj_id;
-
- /* Increment reference count on atom. */
- if (H5I_inc_ref(ret_value)<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed");
+ type = H5I_TYPE(obj_id);
+ if(type == H5I_FILE)
+ {
+ ret_value = obj_id;
+
+ /* Increment reference count on atom. */
+ if (H5I_inc_ref(ret_value)<0)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed");
+ }
+ else if(type == H5I_DATATYPE)
+ {
+ if((ent = H5G_loc(obj_id))==NULL)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "not a named datatype");
+ ret_value = H5F_get_id(ent->file);
+ }
+ else if(type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR)
+ {
+ if((ent = H5G_loc(obj_id))==NULL)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get symbol table info");
+ ret_value = H5F_get_id(ent->file);
+ }
+ else
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID");
- break;
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
- case H5I_DATATYPE:
- if((ent = H5G_loc(obj_id))==NULL)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "not a named datatype");
- ret_value = H5F_get_id(ent->file);
- break;
+/*-------------------------------------------------------------------------
+ * Function: H5Iremove_verify
+ *
+ * Purpose: Removes the specified ID from its type, first checking that the
+ * type of the ID and the type type are the same. Public interface to
+ * H5I_remove_verify.
+ *
+ * Return: Success: A pointer to the object that was removed, the
+ * same pointer which would have been found by
+ * calling H5I_object().
+ *
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *H5Iremove_verify(hid_t id, H5I_type_t id_type)
+{
+ void * ret_value; /* Return value */
- case H5I_GROUP:
- case H5I_DATASET:
- case H5I_ATTR:
- if((ent = H5G_loc(obj_id))==NULL)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get symbol table info");
- ret_value = H5F_get_id(ent->file);
- break;
+ FUNC_ENTER_API(H5Iremove_verify, NULL);
+
+ if( H5I_IS_LIB_TYPE( id_type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
+ }
+
+ /* Remove the id */
+ ret_value = H5I_remove_verify(id, id_type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_remove_verify
+ *
+ * Purpose: Removes the specified ID from its type, first checking that
+ * the ID's type is the same as the ID type supplied as an argument
+ *
+ * Return: Success: A pointer to the object that was removed, the
+ * same pointer which would have been found by
+ * calling H5I_object().
+ *
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Nat Furrer
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5I_remove_verify(hid_t id, H5I_type_t id_type)
+{
+ void * ret_value = NULL; /*return value */
+
+ FUNC_ENTER_NOAPI(H5I_remove_verify, NULL);
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID");
- }
+ /* Argument checking will be performed by H5I_remove() */
+
+ /* Verify that the type of the ID is correct */
+ if(id_type == H5I_TYPE(id))
+ {
+ ret_value = H5I_remove(id);
+ }
done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
+
/*-------------------------------------------------------------------------
* Function: H5I_remove
*
- * Purpose: Removes the specified ID from its group.
+ * Purpose: Removes the specified ID from its type.
*
* Return: Success: A pointer to the object that was removed, the
* same pointer which would have been found by
@@ -906,26 +1221,26 @@ done:
void *
H5I_remove(hid_t id)
{
- H5I_id_group_t *grp_ptr = NULL;/*ptr to the atomic group */
+ H5I_id_type_t *type_ptr = NULL;/*ptr to the atomic type */
H5I_id_info_t *curr_id; /*ptr to the current atom */
H5I_id_info_t *last_id; /*ptr to the last atom */
- H5I_type_t grp; /*atom's atomic group */
+ H5I_type_t type; /*atom's atomic type */
unsigned hash_loc; /*atom's hash table location */
void * ret_value = NULL; /*return value */
FUNC_ENTER_NOAPI(H5I_remove, NULL);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid group");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
/* Get the bucket in which the ID is located */
- hash_loc = (unsigned) H5I_LOC(id, grp_ptr->hash_size);
- curr_id = grp_ptr->id_list[hash_loc];
+ hash_loc = (unsigned) H5I_LOC(id, type_ptr->hash_size);
+ curr_id = type_ptr->id_list[hash_loc];
if (curr_id == NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID");
@@ -940,7 +1255,7 @@ H5I_remove(hid_t id)
if (curr_id != NULL) {
if (last_id == NULL) {
/* ID is the first in the chain */
- grp_ptr->id_list[hash_loc] = curr_id->next;
+ type_ptr->id_list[hash_loc] = curr_id->next;
} else {
last_id->next = curr_id->next;
}
@@ -951,14 +1266,14 @@ H5I_remove(hid_t id)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "invalid ID");
}
- /* Decrement the number of IDs in the group */
- (grp_ptr->ids)--;
+ /* Decrement the number of IDs in the type */
+ (type_ptr->ids)--;
done:
FUNC_LEAVE_NOAPI(ret_value);
}
-
+
/*-------------------------------------------------------------------------
* Function: H5Idec_ref
*
@@ -1001,10 +1316,10 @@ done:
* Function: H5I_dec_ref
*
* Purpose: Decrements the number of references outstanding for an ID.
- * This will fail if the group is not a reference counted group.
- * The ID group's 'free' function will be called for the ID
+ * This will fail if the type is not a reference counted type.
+ * The ID type's 'free' function will be called for the ID
* if the reference count for the ID reaches 0 and a free
- * function has been defined at group creation time.
+ * function has been defined at type creation time.
*
* Return: Success: New reference count.
*
@@ -1025,8 +1340,8 @@ done:
*
* Robb Matzke, 19 Feb 1999
* If the free method is defined and fails then the object is not
- * removed from the group and its reference count is not decremented.
- * The group number is now passed to the free method.
+ * removed from the type and its reference count is not decremented.
+ * The type number is now passed to the free method.
*
* Raymond, 11 Dec 2001
* If the freeing function fails, return failure instead of reference
@@ -1038,8 +1353,8 @@ done:
int
H5I_dec_ref(hid_t id)
{
- H5I_type_t grp; /*group the object is in*/
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_type_t type; /*type the object is in*/
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the new ID */
int ret_value; /* Return value */
@@ -1049,29 +1364,29 @@ H5I_dec_ref(hid_t id)
assert(id>=0);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
/* General lookup of the ID */
if ((id_ptr=H5I_find_id(id))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID");
/*
- * If this is the last reference to the object then invoke the group's
+ * If this is the last reference to the object then invoke the type's
* free method on the object. If the free method is undefined or
- * successful then remove the object from the group; otherwise leave
- * the object in the group without decrementing the reference
+ * successful then remove the object from the type; otherwise leave
+ * the object in the type without decrementing the reference
* count. If the reference count is more than one then decrement the
* reference count without calling the free method.
*
* Beware: the free method may call other H5I functions.
*/
if (1==id_ptr->count) {
- if (!grp_ptr->free_func || (grp_ptr->free_func)(id_ptr->obj_ptr)>=0) {
+ if (!type_ptr->free_func || (type_ptr->free_func)(id_ptr->obj_ptr)>=0) {
H5I_remove(id);
ret_value = 0;
} else {
@@ -1141,8 +1456,8 @@ done:
int
H5I_inc_ref(hid_t id)
{
- H5I_type_t grp; /*group the object is in*/
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_type_t type; /*type the object is in*/
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the ID */
int ret_value; /* Return value */
@@ -1152,12 +1467,12 @@ H5I_inc_ref(hid_t id)
assert(id>=0);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (!grp_ptr || grp_ptr->count<=0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr || type_ptr->count<=0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
/* General lookup of the ID */
if (NULL==(id_ptr=H5I_find_id(id)))
@@ -1226,8 +1541,8 @@ done:
static int
H5I_get_ref(hid_t id)
{
- H5I_type_t grp; /*group the object is in*/
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_type_t type; /*type the object is in*/
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *id_ptr; /*ptr to the ID */
int ret_value; /* Return value */
@@ -1237,12 +1552,12 @@ H5I_get_ref(hid_t id)
assert(id>=0);
/* Check arguments */
- grp = H5I_GRP(id);
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (!grp_ptr || grp_ptr->count<=0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group");
+ type = H5I_TYPE(id);
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr || type_ptr->count<=0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
/* General lookup of the ID */
if (NULL==(id_ptr=H5I_find_id(id)))
@@ -1255,11 +1570,323 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5I_get_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iinc_type_ref
+ *
+ * Purpose: Increments the number of references outstanding for an ID type.
+ *
+ * Return: Success: New reference count
+ * Failure: Negative
+ *
+ * Programmer: Nat Furrer
+ * James Laird
+ * April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Iinc_type_ref(H5I_type_t type)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iinc_type_ref, FAIL);
+ H5TRACE1("Is","It",type);
+
+ /* Check arguments */
+ if (type<=0 || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type");
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ /* Do actual increment operation */
+ if((ret_value = H5I_inc_type_ref(type))<0)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID type ref count");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Iinc_ref() */
+
/*-------------------------------------------------------------------------
+ * Function: H5I_inc_type_ref
+ *
+ * Purpose: Increment the reference count for an ID type.
+ *
+ * Return: Success: The new reference count.
+ *
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * Nat Furrer
+ * Friday, April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5I_inc_type_ref(H5I_type_t type)
+{
+ H5I_id_type_t *type_ptr; /* ptr to the type */
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_inc_type_ref, FAIL);
+
+ /* Sanity check */
+ assert(type>0 && type < H5I_next_type);
+
+ /* Check arguments */
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr )
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ /* Set return value */
+ ret_value=++(type_ptr->count);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Idec_type_ref
+ *
+ * Purpose: Decrements the reference count on an entire type of IDs.
+ * If the type reference count becomes zero then the type is
+ * destroyed along with all atoms in that type regardless of
+ * their reference counts. Destroying IDs involves calling
+ * the free-func for each ID's object and then adding the ID
+ * struct to the ID free list. Public interface to
+ * H5I_dec_type_ref.
+ * Returns the number of references to the type on success; a
+ * return value of 0 means that the type will have to be
+ * re-initialized before it can be used again (and should probably
+ * be set to H5I_UNINIT).
+ *
+ * Return: Number of references to type on success/Negative on failure
+ *
+ * Programmer: Nathaniel Furrer
+ * James Laird
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5Idec_type_ref(H5I_type_t type)
+{
+ herr_t ret_value;
+
+ FUNC_ENTER_API(H5Idec_type_ref, FAIL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_dec_type_ref(type);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_dec_type_ref
+ *
+ * Purpose: Decrements the reference count on an entire type of IDs.
+ * If the type reference count becomes zero then the type is
+ * destroyed along with all atoms in that type regardless of
+ * their reference counts. Destroying IDs involves calling
+ * the free-func for each ID's object and then adding the ID
+ * struct to the ID free list.
+ * Returns the number of references to the type on success; a
+ * return value of 0 means that the type will have to be
+ * re-initialized before it can be used again (and should probably
+ * be set to H5I_UNINIT).
+ *
+ * Return: Number of references to type on success/Negative on failure
+ *
+ * Programmer: Unknown
+ *
+ * Modifications:
+ *
+ * Robb Matzke, 25 Feb 1998
+ * IDs are freed when a type is destroyed.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5I_dec_type_ref(H5I_type_t type)
+{
+ H5I_id_type_t *type_ptr = NULL; /* ptr to the atomic type */
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER_NOAPI(H5I_dec_type_ref, FAIL);
+
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number");
+
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ /*
+ * Decrement the number of users of the atomic type. If this is the
+ * last user of the type then release all atoms from the type and
+ * free all memory it used. The free function is invoked for each atom
+ * being freed.
+ */
+ if (1==type_ptr->count)
+ {
+ H5I_destroy_type(type);
+ ret_value = 0;
+ }
+ else
+ {
+ --(type_ptr->count);
+ ret_value = type_ptr->count;
+ }
+
+ done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iget_type_ref
+ *
+ * Purpose: Retrieves the number of references outstanding for a type.
+ *
+ * Return: Success: Reference count
+ * Failure: Negative
+ *
+ * Programmer: Nat Furrer
+ * James Laird
+ * April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Iget_type_ref(H5I_type_t type)
+{
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Iget_type_ref, FAIL);
+ H5TRACE1("Is","It",type);
+
+ /* Check arguments */
+ if (type<=0 || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type");
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type");
+ }
+
+ /* Do actual retrieve operation */
+ if((ret_value = H5I_get_type_ref(type))<0)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID type ref count");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Iget_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_get_type_ref
+ *
+ * Purpose: Retrieve the reference count for an ID type.
+ *
+ * Return: Success: The reference count.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Nat Furrer
+ * James Laird
+ * April 30, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5I_get_type_ref(H5I_type_t type)
+{
+ H5I_id_type_t *type_ptr; /*ptr to the type */
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_get_type_ref, FAIL);
+
+ /* Sanity check */
+ assert(type>=0);
+
+ /* Check arguments */
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr )
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type");
+
+ /* Set return value */
+ ret_value=type_ptr->count;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5I_get_ref() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Isearch
+ *
+ * Purpose: Apply function FUNC to each member of type TYPE and return a
+ * pointer to the first object for which FUNC returns non-zero.
+ * The FUNC should take a pointer to the object and the KEY as
+ * arguments and return non-zero to terminate the search (zero
+ * to continue). Public interface to H5I_search.
+ *
+ * Limitation: Currently there is no way to start searching from where a
+ * previous search left off.
+ *
+ * Return: Success: The first object in the type for which FUNC
+ * returns non-zero. NULL if FUNC returned zero
+ * for every object in the type.
+ *
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Nathaniel Furrer
+ * Friday, April 23, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
+{
+ void * ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Isearch, NULL);
+
+ if( H5I_IS_LIB_TYPE( type ) )
+ {
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
+ }
+
+ ret_value = H5I_search(type, func, key);
+
+ done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+/*-------------------------------------------------------------------------
* Function: H5I_search
*
- * Purpose: Apply function FUNC to each member of group GRP and return a
+ * Purpose: Apply function FUNC to each member of type TYPE and return a
* pointer to the first object for which FUNC returns non-zero.
* The FUNC should take a pointer to the object and the KEY as
* arguments and return non-zero to terminate the search (zero
@@ -1268,9 +1895,9 @@ done:
* Limitation: Currently there is no way to start searching from where a
* previous search left off.
*
- * Return: Success: The first object in the group for which FUNC
+ * Return: Success: The first object in the type for which FUNC
* returns non-zero. NULL if FUNC returned zero
- * for every object in the group.
+ * for every object in the type.
*
* Failure: NULL
*
@@ -1282,9 +1909,9 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5I_search(H5I_type_t grp, H5I_search_func_t func, void *key)
+H5I_search(H5I_type_t type, H5I_search_func_t func, void *key)
{
- H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */
+ H5I_id_type_t *type_ptr = NULL; /*ptr to the type */
H5I_id_info_t *id_ptr = NULL; /*ptr to the new ID */
H5I_id_info_t *next_id = NULL; /*ptr to the next ID */
unsigned i; /*counter */
@@ -1293,15 +1920,15 @@ H5I_search(H5I_type_t grp, H5I_search_func_t func, void *key)
FUNC_ENTER_NOAPI(H5I_search, NULL);
/* Check arguments */
- if (grp <= H5I_BADID || grp >= H5I_NGROUPS)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid group number");
- grp_ptr = H5I_id_group_list_g[grp];
- if (grp_ptr == NULL || grp_ptr->count <= 0)
- HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid group");
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number");
+ type_ptr = H5I_id_type_list_g[type];
+ if (type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
/* Start at the beginning of the array */
- for (i=0; i<grp_ptr->hash_size; i++) {
- id_ptr = grp_ptr->id_list[i];
+ for (i=0; i<type_ptr->hash_size; i++) {
+ id_ptr = type_ptr->id_list[i];
while (id_ptr) {
next_id= id_ptr->next; /* Protect against ID being deleted in callback */
if ((*func)(id_ptr->obj_ptr, id_ptr->id, key))
@@ -1334,24 +1961,25 @@ done:
static H5I_id_info_t *
H5I_find_id(hid_t id)
{
- H5I_id_group_t *grp_ptr; /*ptr to the group */
+ H5I_id_type_t *type_ptr; /*ptr to the type */
H5I_id_info_t *last_id; /*ptr to the last ID */
H5I_id_info_t *id_ptr; /*ptr to the new ID */
- H5I_type_t grp; /*ID's group */
+ H5I_type_t type; /*ID's type */
unsigned hash_loc; /*bucket pointer */
H5I_id_info_t *ret_value = NULL; /*return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_find_id);
/* Check arguments */
- grp = H5I_GRP(id);
- assert(grp > H5I_BADID && grp < H5I_NGROUPS);
- grp_ptr = H5I_id_group_list_g[grp];
- assert(grp_ptr && grp_ptr->count > 0);
+ type = H5I_TYPE(id);
+ assert(type > H5I_BADID && type < H5I_next_type);
+ type_ptr = H5I_id_type_list_g[type];
+
+ assert(type_ptr && type_ptr->count > 0);
/* Get the bucket in which the ID is located */
- hash_loc = (unsigned)H5I_LOC(id, grp_ptr->hash_size);
- id_ptr = grp_ptr->id_list[hash_loc];
+ hash_loc = (unsigned)H5I_LOC(id, type_ptr->hash_size);
+ id_ptr = type_ptr->id_list[hash_loc];
/* Scan the bucket's linked list for a match */
last_id=NULL;
@@ -1360,8 +1988,8 @@ H5I_find_id(hid_t id)
/* If we found an object, move it to the front of the list, if it isn't there already */
if(last_id!=NULL) {
last_id->next=id_ptr->next;
- id_ptr->next=grp_ptr->id_list[hash_loc];
- grp_ptr->id_list[hash_loc]=id_ptr;
+ id_ptr->next=type_ptr->id_list[hash_loc];
+ type_ptr->id_list[hash_loc]=id_ptr;
} /* end if */
break;
} /* end if */
@@ -1435,7 +2063,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5I_debug
*
- * Purpose: Dump the contents of a group to stderr for debugging.
+ * Purpose: Dump the contents of a type to stderr for debugging.
*
* Return: Success: Non-negative
*
@@ -1453,9 +2081,9 @@ done:
*/
#ifdef H5I_DEBUG_OUTPUT
static herr_t
-H5I_debug(H5I_type_t grp)
+H5I_debug(H5I_type_t type)
{
- H5I_id_group_t *grp_ptr;
+ H5I_id_type_t *type_ptr;
H5I_id_info_t *cur;
H5G_entry_t *ent = NULL;
int is, js;
@@ -1464,21 +2092,21 @@ H5I_debug(H5I_type_t grp)
FUNC_ENTER_NOAPI(H5I_debug, FAIL);
- fprintf(stderr, "Dumping group %d\n", (int)grp);
- grp_ptr = H5I_id_group_list_g[grp];
+ fprintf(stderr, "Dumping ID type %d\n", (int)type);
+ type_ptr = H5I_id_type_list_g[type];
/* Header */
- fprintf(stderr, " count = %u\n", grp_ptr->count);
- fprintf(stderr, " reserved = %u\n", grp_ptr->reserved);
- fprintf(stderr, " wrapped = %u\n", grp_ptr->wrapped);
- fprintf(stderr, " hash_size = %lu\n", (unsigned long)grp_ptr->hash_size);
- fprintf(stderr, " ids = %u\n", grp_ptr->ids);
- fprintf(stderr, " nextid = %u\n", grp_ptr->nextid);
+ fprintf(stderr, " count = %u\n", type_ptr->count);
+ fprintf(stderr, " reserved = %u\n", type_ptr->reserved);
+ fprintf(stderr, " wrapped = %u\n", type_ptr->wrapped);
+ fprintf(stderr, " hash_size = %lu\n", (unsigned long)type_ptr->hash_size);
+ fprintf(stderr, " ids = %u\n", type_ptr->ids);
+ fprintf(stderr, " nextid = %u\n", type_ptr->nextid);
/* Cache */
fprintf(stderr, " Cache:\n");
for (is=0; is<ID_CACHE_SIZE; is++) {
- if (H5I_cache_g[is] && H5I_GRP(H5I_cache_g[is]->id)==grp) {
+ if (H5I_cache_g[is] && H5I_TYPE(H5I_cache_g[is]->id)==type) {
fprintf(stderr, " Entry-%d, ID=%lu\n",
is, (unsigned long)(H5I_cache_g[is]->id));
}
@@ -1486,15 +2114,15 @@ H5I_debug(H5I_type_t grp)
/* List */
fprintf(stderr, " List:\n");
- for (iu=0; iu<grp_ptr->hash_size; iu++) {
- for (js=0, cur=grp_ptr->id_list[iu]; cur; cur=cur->next, js++) {
+ for (iu=0; iu<type_ptr->hash_size; iu++) {
+ for (js=0, cur=type_ptr->id_list[iu]; cur; cur=cur->next, js++) {
fprintf(stderr, " #%u.%d\n", iu, js);
fprintf(stderr, " id = %lu\n", (unsigned long)(cur->id));
fprintf(stderr, " count = %u\n", cur->count);
fprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(cur->obj_ptr));
/* Get the symbol table entry, so we get get the name */
- switch(grp) {
+ switch(type) {
case H5I_GROUP:
ent = H5G_entof((H5G_t*)cur->obj_ptr);
break;
diff --git a/src/H5Ipkg.h b/src/H5Ipkg.h
index aab865c..d172f97 100644
--- a/src/H5Ipkg.h
+++ b/src/H5Ipkg.h
@@ -37,23 +37,25 @@
/**************************/
/*
- * Number of bits to use for Group ID in each atom. Increase if H5I_NGROUPS
- * becomes too large (an assertion would fail in H5I_init_interface). This is
- * the only number that must be changed since all other bit field sizes and
- * masks are calculated from GROUP_BITS.
+ * Number of bits to use for ID Type in each atom. Increase if more types
+ * are needed (though this will decrease the number of available IDs per
+ * type). This is the only number that must be changed since all other bit
+ * field sizes and masks are calculated from TYPE_BITS.
*/
-#define GROUP_BITS 5
-#define GROUP_MASK ((1<<GROUP_BITS)-1)
+#define TYPE_BITS 7
+#define TYPE_MASK ((1<<TYPE_BITS)-1)
+
+#define MAX_NUM_TYPES TYPE_MASK
/*
* Number of bits to use for the Atom index in each atom (assumes 8-bit
* bytes). We don't use the sign bit.
*/
-#define ID_BITS ((sizeof(hid_t)*8)-(GROUP_BITS+1))
+#define ID_BITS ((sizeof(hid_t)*8)-(TYPE_BITS+1))
#define ID_MASK ((1<<ID_BITS)-1)
-/* Map an atom to a Group number */
-#define H5I_GRP(a) ((H5I_type_t)(((hid_t)(a)>>ID_BITS) & GROUP_MASK))
+/* Map an atom to an ID type number */
+#define H5I_TYPE(a) ((H5I_type_t)(((hid_t)(a)>>ID_BITS) & TYPE_MASK))
/****************************/
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 79819a5..3f6b65c 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -27,7 +27,10 @@
/* Private headers needed by this file */
#include "H5private.h"
-/* Default sizes of the hash-tables for various atom groups */
+/* Macro to determine if a H5I_type_t is a "library type" */
+#define H5I_IS_LIB_TYPE( type ) (type > 0 && type < H5I_NTYPES)
+
+/* Default sizes of the hash-tables for various atom types */
#define H5I_ERRSTACK_HASHSIZE 64
#define H5I_FILEID_HASHSIZE 64
#define H5I_TEMPID_HASHSIZE 64
@@ -45,30 +48,21 @@
#define H5I_ERRMSG_HASHSIZE 64
#define H5I_ERRSTK_HASHSIZE 64
-/*
- * Function for freeing objects. This function will be called with an object
- * ID group number (object type) and a pointer to the object. The function
- * should free the object and return non-negative to indicate that the object
- * can be removed from the ID group. If the function returns negative
- * (failure) then the object will remain in the ID group.
- */
-typedef herr_t (*H5I_free_t)(void*);
-
-/* Type of the function to compare objects & keys */
-typedef int (*H5I_search_func_t)(void *obj, hid_t id, void *key);
-
/* Private Functions in H5I.c */
-H5_DLL int H5I_init_group(H5I_type_t grp, size_t hash_size, unsigned reserved,
- H5I_free_t func);
-H5_DLL int H5I_nmembers(H5I_type_t grp);
-H5_DLL herr_t H5I_clear_group(H5I_type_t grp, hbool_t force);
-H5_DLL herr_t H5I_destroy_group(H5I_type_t grp);
-H5_DLL hid_t H5I_register(H5I_type_t grp, void *object);
+H5_DLL H5I_type_t H5I_register_type(H5I_type_t type_id, size_t hash_size, unsigned reserved, H5I_free_t free_func);
+H5_DLL int H5I_nmembers(H5I_type_t type);
+H5_DLL herr_t H5I_clear_type(H5I_type_t type, hbool_t force);
+H5_DLL int H5I_destroy_type(H5I_type_t type);
+H5_DLL hid_t H5I_register(H5I_type_t type, void *object);
H5_DLL void *H5I_object(hid_t id);
H5_DLL void *H5I_object_verify(hid_t id, H5I_type_t id_type);
H5_DLL H5I_type_t H5I_get_type(hid_t id);
H5_DLL void *H5I_remove(hid_t id);
-H5_DLL void *H5I_search(H5I_type_t grp, H5I_search_func_t func, void *key);
+H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
+H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key);
H5_DLL int H5I_inc_ref(hid_t id);
H5_DLL int H5I_dec_ref(hid_t id);
+H5_DLL int H5I_inc_type_ref(H5I_type_t type);
+H5_DLL herr_t H5I_dec_type_ref(H5I_type_t type);
+H5_DLL int H5I_get_type_ref(H5I_type_t type);
#endif
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 9c4d950..c8787c9 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -23,32 +23,34 @@
#include "H5public.h"
/*
- * Group values allowed. Start with `1' instead of `0' because it makes the
+ * Library type values. Start with `1' instead of `0' because it makes the
* tracing output look better when hid_t values are large numbers. Change the
- * GROUP_BITS in H5I.c if the MAXID gets larger than 32 (an assertion will
+ * TYPE_BITS in H5I.c if the MAXID gets larger than 32 (an assertion will
* fail otherwise).
*
- * When adding groups here, add a section to the 'misc19' test in test/tmisc.c
+ * When adding types here, add a section to the 'misc19' test in test/tmisc.c
* to verify that the H5I{inc|dec|get}_ref() routines work correctly with in.
*
*/
typedef enum {
- H5I_BADID = (-1), /*invalid Group */
- H5I_FILE = 1, /*group ID for File objects */
+ H5I_UNINIT = (-2), /*uninitialized type */
+ H5I_BADID = (-1), /*invalid Type */
+ H5I_FILE = 1, /*type ID for File objects */
H5I_FILE_CLOSING, /*files pending close due to open objhdrs */
- 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_REFERENCE, /*group ID for Reference objects */
- 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_ERROR_CLASS, /*group ID for error classes */
- H5I_ERROR_MSG, /*group ID for error messages */
- H5I_ERROR_STACK, /*group ID for error stacks */
- H5I_NGROUPS /*number of valid groups, MUST BE LAST! */
+ H5I_GROUP, /*type ID for Group objects */
+ H5I_DATATYPE, /*type ID for Datatype objects */
+ H5I_DATASPACE, /*type ID for Dataspace objects */
+ H5I_DATASET, /*type ID for Dataset objects */
+ H5I_ATTR, /*type ID for Attribute objects */
+ H5I_TEMPBUF, /*type ID for Temporary buffer objects */
+ H5I_REFERENCE, /*type ID for Reference objects */
+ H5I_VFL, /*type ID for virtual file layer */
+ H5I_GENPROP_CLS, /*type ID for generic property list classes */
+ H5I_GENPROP_LST, /*type ID for generic property lists */
+ H5I_ERROR_CLASS, /*type ID for error classes */
+ H5I_ERROR_MSG, /*type ID for error messages */
+ H5I_ERROR_STACK, /*type ID for error stacks */
+ H5I_NTYPES /*number of library types, MUST BE LAST! */
} H5I_type_t;
/* Type of atoms to return to users */
@@ -57,17 +59,42 @@ typedef int hid_t;
/* An invalid object ID. This is also negative for error return. */
#define H5I_INVALID_HID (-1)
+/*
+ * Function for freeing objects. This function will be called with an object
+ * ID type number and a pointer to the object. The function should free the
+ * object and return non-negative to indicate that the object
+ * can be removed from the ID type. If the function returns negative
+ * (failure) then the object will remain in the ID type.
+ */
+typedef herr_t (*H5I_free_t)(void*);
+
+/* Type of the function to compare objects & keys */
+typedef int (*H5I_search_func_t)(void *obj, hid_t id, void *key);
+
#ifdef __cplusplus
extern "C" {
#endif
/* Public API functions */
+
+H5_DLL hid_t H5Iregister(H5I_type_t type, void *object);
+H5_DLL void *H5Iobject_verify(hid_t id, H5I_type_t id_type);
+H5_DLL void *H5Iremove_verify(hid_t id, H5I_type_t id_type);
H5_DLL H5I_type_t H5Iget_type(hid_t id);
H5_DLL hid_t H5Iget_file_id(hid_t id);
H5_DLL ssize_t H5Iget_name(hid_t id, char *name/*out*/, size_t size);
H5_DLL int H5Iinc_ref(hid_t id);
H5_DLL int H5Idec_ref(hid_t id);
H5_DLL int H5Iget_ref(hid_t id);
+H5_DLL H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func);
+H5_DLL herr_t H5Iclear_type(H5I_type_t type, hbool_t force);
+H5_DLL herr_t H5Idestroy_type(H5I_type_t type);
+H5_DLL int H5Iinc_type_ref(H5I_type_t type);
+H5_DLL int H5Idec_type_ref(H5I_type_t type);
+H5_DLL int H5Iget_type_ref(H5I_type_t type);
+H5_DLL void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key);
+H5_DLL int H5Inmembers(H5I_type_t type);
+
#ifdef __cplusplus
}
diff --git a/src/H5P.c b/src/H5P.c
index cc0eca8..2c198ce 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -216,9 +216,9 @@ H5P_init_interface(void)
/*
* Initialize the Generic Property class & object groups.
*/
- if (H5I_init_group(H5I_GENPROP_CLS, H5I_GENPROPCLS_HASHSIZE, 0, (H5I_free_t)H5P_close_class) < 0)
+ if (H5I_register_type(H5I_GENPROP_CLS, H5I_GENPROPCLS_HASHSIZE, 0, (H5I_free_t)H5P_close_class) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group");
- if (H5I_init_group(H5I_GENPROP_LST, H5I_GENPROPOBJ_HASHSIZE, 0, (H5I_free_t)H5P_close) < 0)
+ if (H5I_register_type(H5I_GENPROP_LST, H5I_GENPROPOBJ_HASHSIZE, 0, (H5I_free_t)H5P_close) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group");
/* Create root property list class */
@@ -324,7 +324,7 @@ H5P_term_interface(void)
if (n) {
/* Clear the lists */
if(nlist>0) {
- H5I_clear_group(H5I_GENPROP_LST, FALSE);
+ H5I_clear_type(H5I_GENPROP_LST, FALSE);
/* Reset the default property lists, if they've been closed */
if(H5I_nmembers(H5I_GENPROP_LST)==0) {
@@ -339,7 +339,7 @@ H5P_term_interface(void)
/* Only attempt to close the classes after all the lists are closed */
if(nlist==0 && nclass>0) {
- H5I_clear_group(H5I_GENPROP_CLS, FALSE);
+ H5I_clear_type(H5I_GENPROP_CLS, FALSE);
/* Reset the default property lists, if they've been closed */
if(H5I_nmembers(H5I_GENPROP_CLS)==0) {
@@ -352,9 +352,9 @@ H5P_term_interface(void)
} /* end if */
} /* end if */
} else {
- H5I_destroy_group(H5I_GENPROP_LST);
+ H5I_dec_type_ref(H5I_GENPROP_LST);
n++; /*H5I*/
- H5I_destroy_group(H5I_GENPROP_CLS);
+ H5I_dec_type_ref(H5I_GENPROP_CLS);
n++; /*H5I*/
interface_initialize_g = 0;
diff --git a/src/H5R.c b/src/H5R.c
index df1041a..72e629d 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -60,7 +60,7 @@ H5R_init_interface(void)
FUNC_ENTER_NOAPI_NOINIT(H5R_init_interface);
/* Initialize the atom group for the file IDs */
- if (H5I_init_group(H5I_REFERENCE, H5I_REFID_HASHSIZE, H5R_RESERVED_ATOMS,
+ if (H5I_register_type(H5I_REFERENCE, H5I_REFID_HASHSIZE, H5R_RESERVED_ATOMS,
(H5I_free_t)NULL)<0)
HGOTO_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to initialize interface");
@@ -95,9 +95,9 @@ H5R_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_REFERENCE))) {
- H5I_clear_group(H5I_REFERENCE, FALSE);
+ H5I_clear_type(H5I_REFERENCE, FALSE);
} else {
- H5I_destroy_group(H5I_REFERENCE);
+ H5I_dec_type_ref(H5I_REFERENCE);
interface_initialize_g = 0;
n = 1; /*H5I*/
}
diff --git a/src/H5S.c b/src/H5S.c
index 0de9190..1001395 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -85,7 +85,7 @@ H5S_init_interface(void)
FUNC_ENTER_NOAPI_NOINIT(H5S_init_interface);
/* Initialize the atom group for the file IDs */
- if (H5I_init_group(H5I_DATASPACE, H5I_DATASPACEID_HASHSIZE,
+ if (H5I_register_type(H5I_DATASPACE, H5I_DATASPACEID_HASHSIZE,
H5S_RESERVED_ATOMS, (H5I_free_t)H5S_close)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface");
@@ -136,7 +136,7 @@ H5S_term_interface(void)
if (interface_initialize_g) {
if ((n=H5I_nmembers(H5I_DATASPACE))) {
- H5I_clear_group(H5I_DATASPACE, FALSE);
+ H5I_clear_type(H5I_DATASPACE, FALSE);
} else {
#ifdef H5S_DEBUG
/*
@@ -256,7 +256,7 @@ H5S_term_interface(void)
#endif
/* Free data types */
- H5I_destroy_group(H5I_DATASPACE);
+ H5I_dec_type_ref(H5I_DATASPACE);
/* Clear/free conversion table */
for (i=0; i<H5S_nconv_g; i++)
diff --git a/src/H5T.c b/src/H5T.c
index e2ed12d..474768f 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -693,7 +693,7 @@ H5T_init_interface(void)
FUNC_ENTER_NOAPI_NOINIT(H5T_init_interface);
/* Initialize the atom group for the file IDs */
- if (H5I_init_group(H5I_DATATYPE, H5I_DATATYPEID_HASHSIZE, H5T_RESERVED_ATOMS, (H5I_free_t)H5T_close)<0)
+ if (H5I_register_type(H5I_DATATYPE, H5I_DATATYPEID_HASHSIZE, H5T_RESERVED_ATOMS, (H5I_free_t)H5T_close)<0)
HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize interface");
/* Make certain there aren't too many classes of datatypes defined */
@@ -1301,7 +1301,7 @@ H5T_term_interface(void)
/* Unlock all datatypes, then free them */
H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL);
- H5I_destroy_group(H5I_DATATYPE);
+ H5I_dec_type_ref(H5I_DATATYPE);
/* Reset all the datatype IDs */
H5T_IEEE_F32BE_g = FAIL;
diff --git a/test/Makefile.in b/test/Makefile.in
index 44d5681..65ff6d6 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -79,7 +79,7 @@ TEST_SRC=big.c bittests.c cmpd_dset.c dsets.c dtypes.c extend.c \
istore.c lheap.c links.c mount.c mtime.c ohdr.c stab.c tarray.c \
tattr.c tconfig.c testhdf5.c testmeta.c tfile.c \
tgenprop.c th5s.c theap.c titerate.c tmeta.c trefer.c trefstr.c \
- tselect.c ttime.c ttbbt.c ttst.c tvltypes.c tvlstr.c tmisc.c \
+ tselect.c ttime.c ttbbt.c ttst.c tvltypes.c tvlstr.c tmisc.c tid.c \
unlink.c enum.c ttsafe.c ttsafe_dcreate.c ttsafe_error.c \
ttsafe_cancel.c ttsafe_acreate.c gass_write.c gass_read.c \
gass_append.c srb_read.c srb_write.c srb_append.c stream_test.c \
@@ -112,7 +112,8 @@ $(PROGS): $(LIB) $(LIBHDF5)
TESTHDF5_OBJ=testhdf5.lo tarray.lo tattr.lo tconfig.lo tfile.lo \
tgenprop.lo th5s.lo theap.lo titerate.lo tmeta.lo ttime.lo trefer.lo \
- trefstr.lo tselect.lo ttbbt.lo ttst.lo tvltypes.lo tvlstr.lo tmisc.lo
+ trefstr.lo tselect.lo ttbbt.lo ttst.lo tvltypes.lo tvlstr.lo tmisc.lo \
+ tid.lo
TTS_OBJ=ttsafe.lo ttsafe_dcreate.lo ttsafe_error.lo \
ttsafe_cancel.lo ttsafe_acreate.lo
diff --git a/test/testhdf5.c b/test/testhdf5.c
index e9941de..38193fc 100644
--- a/test/testhdf5.c
+++ b/test/testhdf5.c
@@ -64,6 +64,7 @@ main(int argc, char *argv[])
AddTest("array", test_array, cleanup_array, "Array Datatypes", NULL);
AddTest("genprop", test_genprop, cleanup_genprop, "Generic Properties", NULL);
AddTest("misc", test_misc, cleanup_misc, "Miscellaneous", NULL);
+ AddTest("id", test_ids, NULL, "Public ID Functions", NULL);
/* Display testing information */
TestInfo(argv[0]);
diff --git a/test/testhdf5.h b/test/testhdf5.h
index 15c9fe1..f01a32e 100644
--- a/test/testhdf5.h
+++ b/test/testhdf5.h
@@ -197,6 +197,7 @@ void test_array(void);
void test_genprop(void);
void test_configure(void);
void test_misc(void);
+void test_ids(void);
/* Prototypes for the cleanup routines */
void cleanup_metadata(void);
diff --git a/test/tid.c b/test/tid.c
new file mode 100644
index 0000000..2ad8481
--- /dev/null
+++ b/test/tid.c
@@ -0,0 +1,344 @@
+
+#include "testhdf5.h"
+#include "hdf5.h"
+
+ /* Include H5Ipkg.h to calculate max number of groups */
+#define H5I_PACKAGE
+#include "H5Ipkg.h"
+
+ /* Test basic functionality of registering and deleting types and IDs */
+int id_test()
+{
+ H5I_type_t myType = H5I_BADID;
+ hid_t arrayID = H5I_INVALID_HID;
+ void* testObj;
+ void* testPtr = NULL;
+ char nameString[10];
+ hid_t testID;
+ ssize_t testSize = -1;
+ herr_t err;
+ int num_ref;
+
+ testObj = malloc(7 * sizeof(int));
+
+ /* Try to register an ID with ficticious type #420 */
+ H5E_BEGIN_TRY
+ arrayID = H5Iregister((H5I_type_t) 420, testObj);
+ H5E_END_TRY
+
+ VERIFY(arrayID, H5I_INVALID_HID, "H5Iregister");
+ if(arrayID != H5I_INVALID_HID)
+ goto out;
+
+ /* Register a type */
+ myType = H5Iregister_type(64, 0, (H5I_free_t) free );
+
+ CHECK(myType, H5I_BADID, "H5Iregister_type");
+ if(myType == H5I_BADID)
+ goto out;
+
+ /* Register an ID and retrieve the object it points to */
+ arrayID = H5Iregister(myType, testObj);
+
+ CHECK(arrayID, H5I_INVALID_HID, "H5Iregister");
+ if(arrayID == H5I_INVALID_HID)
+ goto out;
+
+ testPtr = (int *) H5Iobject_verify(arrayID, myType);
+
+ VERIFY(testPtr, testObj, "H5Iobject_verify");
+ if(testPtr != testObj)
+ goto out;
+
+ /* Ensure that H5Iget_file_id and H5Iget_name() fail */
+ H5E_BEGIN_TRY
+ testID = H5Iget_file_id(arrayID);
+ H5E_END_TRY
+
+ VERIFY(testID, H5I_INVALID_HID, "H5Iget_file_id");
+ if(testID != H5I_INVALID_HID)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testSize = H5Iget_name(arrayID, nameString, 9);
+ H5E_END_TRY
+
+ VERIFY(testSize, 0, "H5Iget_name");
+ if(testSize != 0)
+ goto out;
+
+ /* Make sure H5Iremove_verify catches objects of the wrong type */
+ H5E_BEGIN_TRY
+ testPtr = (int*) H5Iremove_verify(arrayID, (H5I_type_t) 0);
+ H5E_END_TRY
+
+ VERIFY(testPtr, NULL, "H5Iremove_verify");
+ if(testPtr != NULL)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testPtr = (int*) H5Iremove_verify(arrayID, (H5I_type_t) ((int) myType-1));
+ H5E_END_TRY
+
+ VERIFY(testPtr, NULL, "H5Iremove_verify");
+ if(testPtr != NULL)
+ goto out;
+
+ /* Remove an ID and make sure we can't access it */
+ testPtr = (int*) H5Iremove_verify(arrayID, myType);
+
+ CHECK(testPtr, NULL, "H5Iremove_verify");
+ if(testPtr == NULL)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testPtr = (int*) H5Iobject_verify(arrayID, myType);
+ H5E_END_TRY
+
+ VERIFY(testPtr, NULL, "H5Iobject_verify");
+ if(testPtr != NULL)
+ goto out;
+
+ /* Delete the type and make sure we can't access objects within it */
+ arrayID = H5Iregister(myType, testObj);
+
+ err = H5Idestroy_type(myType);
+ VERIFY(err, 0, "H5Idestroy_type");
+ if( err != 0)
+ goto out;
+ VERIFY(H5Inmembers(myType), 0, "H5Inmembers");
+ if(H5Inmembers(myType) != 0)
+ goto out;
+
+ /* Register another type and another object in that type */
+ myType = H5Iregister_type(64, 0, (H5I_free_t) free );
+
+ CHECK(myType, H5I_BADID, "H5Iregister_type");
+ if(myType == H5I_BADID)
+ goto out;
+
+ testObj = malloc(7 * sizeof(int));
+ arrayID = H5Iregister(myType, testObj);
+
+ CHECK(arrayID, H5I_INVALID_HID, "H5Iregister");
+ if(arrayID == H5I_INVALID_HID)
+ goto out;
+ VERIFY(H5Inmembers(myType), 1, "H5Inmembers");
+ if(H5Inmembers(myType) != 1)
+ goto out;
+
+ /* Increment references to type and ensure that dec_type_ref
+ doesn't destroy the type */
+ num_ref = H5Iinc_type_ref(myType);
+ VERIFY(num_ref, 2, "H5Iinc_type_ref");
+ if( num_ref != 2)
+ goto out;
+ num_ref = H5Idec_type_ref(myType);
+ VERIFY(num_ref, 1, "H5Idec_type_ref");
+ if(num_ref != 1)
+ goto out;
+ VERIFY(H5Inmembers(myType), 1, "H5Inmembers");
+ if(H5Inmembers(myType) != 1)
+ goto out;
+
+ /* This call to dec_type_ref should destroy the type */
+ num_ref = H5Idec_type_ref(myType);
+ VERIFY(num_ref, 0, "H5Idec_type_ref");
+ if(num_ref != 0)
+ goto out;
+ VERIFY(H5Inmembers(myType), 0, "H5Inmembers");
+ if(H5Inmembers(myType) != 0)
+ goto out;
+
+ return 0;
+
+out:
+ /* Clean up type if it has been allocated */
+ if(myType >= 0)
+ H5Idestroy_type(myType);
+
+ return -1;
+}
+
+
+ /* A dummy search function for the next test */
+int test_search_func(void * ptr1, void * ptr2);
+int test_search_func(void * ptr1, void * ptr2) { return 0; }
+
+ /* Ensure that public functions cannot access "predefined" ID types */
+int id_predefined_test()
+{
+ void * testObj;
+ hid_t testID;
+ hid_t typeID = H5I_INVALID_HID;
+ int testInt;
+ void * testPtr;
+ herr_t testErr;
+
+ testObj = malloc(sizeof(int));
+
+ /* Try to perform illegal functions on various predefined types */
+ H5E_BEGIN_TRY
+ testID = H5Iregister(H5I_FILE, testObj);
+ H5E_END_TRY
+
+ VERIFY(testID, H5I_INVALID_HID, "H5Iregister");
+ if(testID != H5I_INVALID_HID)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testPtr = H5Isearch(H5I_GENPROP_LST, (H5I_search_func_t) test_search_func, testObj);
+ H5E_END_TRY
+
+ VERIFY(testPtr, NULL, "H5Isearch");
+ if(testPtr != NULL)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testInt = H5Inmembers(H5I_ERROR_STACK);
+ H5E_END_TRY
+
+ VERIFY(testInt, -1, "H5Inmembers");
+ if(testInt != -1)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testErr = H5Iclear_type(H5I_FILE, 0);
+ H5E_END_TRY
+
+ VERIFY((testErr >= 0), 0, "H5Iclear_type");
+ if(testErr >= 0)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testErr = H5Idestroy_type(H5I_DATASET);
+ H5E_END_TRY
+
+ VERIFY((testErr >= 0), 0, "H5Idestroy_type");
+ if(testErr >= 0)
+ goto out;
+
+ /* Create a datatype ID and try to perform illegal functions on it */
+ typeID = H5Tcreate(H5T_OPAQUE, 42);
+ CHECK(typeID, H5I_INVALID_HID, "H5Tcreate");
+ if(typeID == H5I_INVALID_HID)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testPtr = H5Iremove_verify(typeID, H5I_DATATYPE);
+ H5E_END_TRY
+
+ VERIFY(testPtr, NULL, "H5Iremove_verify");
+ if(testPtr != NULL)
+ goto out;
+
+ H5E_BEGIN_TRY
+ testPtr = H5Iobject_verify(typeID, H5I_DATATYPE);
+ H5E_END_TRY
+
+ VERIFY(testPtr, NULL, "H5Iobject_verify");
+ if(testPtr != NULL)
+ goto out;
+
+ H5Tclose(typeID);
+
+ return 0;
+
+out:
+ if(typeID != H5I_INVALID_HID)
+ H5Tclose(typeID);
+
+ return -1;
+}
+
+
+ /* Test boundary cases with lots of types */
+
+ /* Type IDs range from H5I_NTYPES to MAX_NUM_TYPES. The system will assign */
+ /* IDs in sequential order until MAX_NUM_TYPES IDs have been given out, at which */
+ /* point it will search for type IDs that were allocated but have since been */
+ /* deleted. */
+ /* This test will allocate IDs up to MAX_NUM_TYPES, ensure that IDs wrap around */
+ /* to low values successfully, ensure that an error is thrown when all possible */
+ /* type IDs are taken, then ensure that deleting types frees up their IDs. */
+ /* Note that this test depends on the implementation of IDs, so may break */
+ /* if the implementation changes. */
+ /* Also note that if someone else registered a user-defined type and forgot to */
+ /* destroy it, this test will mysteriously fail (because it will expect there to */
+ /* be one more "free" type ID than there is). */
+ /* H5I_NTYPES is defined in h5public.h, MAX_NUM_TYPES is defined in h5pkg.h */
+int test_id_type_list()
+{
+ H5I_type_t startType; /* The first type ID we were assigned in this test */
+ H5I_type_t currentType;
+ H5I_type_t testType;
+ int i; /* Just a counter variable */
+
+ startType = H5Iregister_type(8, 0, (H5I_free_t) free );
+ CHECK(startType, H5I_BADID, "H5Iregister_type");
+ if(startType == H5I_BADID)
+ goto out;
+
+ /* Sanity check */
+ if(startType >= MAX_NUM_TYPES || startType < H5I_NTYPES)
+ {
+ /* Error condition, throw an error */
+ CHECK(1, 1, "H5Iregister_type");
+ goto out;
+ }
+ /* Create types up to MAX_NUM_TYPES */
+ for(i = startType + 1; i < MAX_NUM_TYPES; i++)
+ {
+ currentType = H5Iregister_type(8, 0, (H5I_free_t) free );
+ CHECK(currentType, H5I_BADID, "H5Iregister_type");
+ if(currentType == H5I_BADID)
+ goto out;
+ }
+
+ /* Wrap around to low type ID numbers */
+ for(i = H5I_NTYPES; i < startType; i++)
+ {
+ currentType = H5Iregister_type(8, 0, (H5I_free_t) free );
+ CHECK(currentType, H5I_BADID, "H5Iregister_type");
+ if(currentType == H5I_BADID)
+ goto out;
+ }
+
+ /* There should be no room at the inn */
+ H5E_BEGIN_TRY
+ testType = H5Iregister_type(8, 0, (H5I_free_t) free );
+ H5E_END_TRY
+
+ VERIFY(testType, H5I_BADID, "H5Iregister_type");
+ if(testType != H5I_BADID)
+ goto out;
+
+ /* Now delete a type and try to insert again */
+ H5Idestroy_type(H5I_NTYPES);
+ testType = H5Iregister_type(8, 0, (H5I_free_t) free );
+
+ VERIFY(testType, H5I_NTYPES, "H5Iregister_type");
+ if(testType != H5I_NTYPES)
+ goto out;
+
+ /* Cleanup. Destroy all types. */
+ for(i = H5I_NTYPES; i < MAX_NUM_TYPES; i++)
+ H5Idestroy_type((H5I_type_t) i);
+
+ return 0;
+
+out:
+ /* Cleanup. For simplicity, just destroy all types and ignore errors. */
+ H5E_BEGIN_TRY
+ for(i = H5I_NTYPES; i < MAX_NUM_TYPES; i++)
+ H5Idestroy_type((H5I_type_t) i);
+ H5E_END_TRY
+ return -1;
+}
+
+void test_ids()
+{
+ id_test();
+ id_predefined_test();
+ test_id_type_list();
+} \ No newline at end of file