summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5I.c47
-rw-r--r--src/H5Ipublic.h1
-rw-r--r--test/tid.c86
4 files changed, 132 insertions, 4 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 8f2c381..0f20d6f 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -51,6 +51,8 @@ New Features
Library:
--------
+ - Added H5Iis_valid() function to check if an id is valid without producing
+ an error message. (NAF - 2008/11/5)
- Added two new public routines: H5Pget_elink_fapl() and
H5Pset_elink_fapl(). (see bug #1247) (VC - 2008/10/13)
- Improved free space tracking in file to be faster. (QAK - 2008/10/06)
diff --git a/src/H5I.c b/src/H5I.c
index 40fec88..f29624b 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -1844,6 +1844,53 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Iis_valid
+ *
+ * Purpose: Check if the given id is valid. And id is valid if it is in
+ * use and has an application reference count of at least 1.
+ *
+ * Return: Success: TRUE if the id is valid, FALSE otherwise.
+ *
+ * Failure: Negative (never fails currently)
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 31, 2008 (boo)
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Iis_valid(hid_t id)
+{
+ H5I_id_type_t *type_ptr; /* ptr to ID's type */
+ H5I_id_info_t *id_ptr; /* ptr to the ID */
+ H5I_type_t type; /* ID's type */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_API(H5Iis_valid, FAIL)
+
+ type = H5I_TYPE(id);
+ /* Check for conditions that would cause H5I_find_id to throw an assertion */
+ if (type <= H5I_BADID || type >= H5I_next_type)
+ HGOTO_DONE(FALSE);
+
+ type_ptr = H5I_id_type_list_g[type];
+ if (!type_ptr || type_ptr->count <= 0)
+ ret_value = FALSE;
+
+ /* Find the ID */
+ else if (NULL == (id_ptr = H5I_find_id(id)))
+ ret_value = FALSE;
+
+ /* Check if the found id is an internal id */
+ else if (!id_ptr->app_count)
+ ret_value = FALSE;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iis_valid() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Isearch
*
* Purpose: Apply function FUNC to each member of type TYPE and return a
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 108f040..608bc9c 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -95,6 +95,7 @@ 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 herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members);
H5_DLL htri_t H5Itype_exists(H5I_type_t type);
+H5_DLL htri_t H5Iis_valid(hid_t id);
#ifdef __cplusplus
}
diff --git a/test/tid.c b/test/tid.c
index 8eb4e24..f3c00fc 100644
--- a/test/tid.c
+++ b/test/tid.c
@@ -112,7 +112,7 @@ static int basic_id_test(void)
H5E_END_TRY
VERIFY(testSize, -1, "H5Iget_name");
- if(testSize != 0)
+ if(testSize != -1)
goto out;
/* Make sure H5Iremove_verify catches objects of the wrong type */
@@ -332,6 +332,83 @@ out:
}
+/* Test the H5Iis_valid function */
+static int test_is_valid(void)
+{
+ hid_t dtype; /* datatype id */
+ int nmembs1; /* number of type memnbers */
+ int nmembs2;
+ htri_t tri_ret; /* htri_t return value */
+ herr_t ret; /* return value */
+
+ /* Create a datatype id */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ if (dtype < 0)
+ goto out;
+
+ /* Check that the ID is valid */
+ tri_ret = H5Iis_valid(dtype);
+ VERIFY(tri_ret, TRUE, "H5Iis_valid");
+ if (tri_ret != TRUE)
+ goto out;
+
+ /* Artificially manipulate the reference counts so app_count is 0, and dtype
+ * appears to be an internal id. This takes advantage of the fact that
+ * H5Ipkg is included.
+ */
+ ret = H5I_inc_ref(dtype, FALSE);
+ CHECK(ret, FAIL, "H5I_inc_ref");
+ if (ret < 0)
+ goto out;
+ ret = H5I_dec_ref(dtype, TRUE);
+ CHECK(ret, FAIL, "H5I_dec_ref");
+ if (ret < 0)
+ goto out;
+
+ /* Check that dtype is invalid */
+ tri_ret = H5Iis_valid(dtype);
+ VERIFY(tri_ret, FALSE, "H5Iis_valid");
+ if (tri_ret != FALSE)
+ goto out;
+
+ /* Close dtype and verify that it has been closed */
+ nmembs1 = H5I_nmembers(H5I_DATATYPE);
+ CHECK(nmembs1, FAIL, "H5I_nmembers");
+ if (nmembs1 < 0)
+ goto out;
+ ret = H5I_dec_ref(dtype, FALSE);
+ CHECK(ret, FAIL, "H5I_dec_ref");
+ if (ret < 0)
+ goto out;
+ nmembs2 = H5I_nmembers(H5I_DATATYPE);
+ VERIFY(nmembs2, nmembs1 - 1, "H5I_nmembers");
+ if (nmembs2 != nmembs1 - 1)
+ goto out;
+
+ /* Check that dtype is invalid */
+ tri_ret = H5Iis_valid(dtype);
+ VERIFY(tri_ret, FALSE, "H5Iis_valid");
+ if (tri_ret != FALSE)
+ goto out;
+
+ /* Check that an id of -1 is invalid */
+ tri_ret = H5Iis_valid(-1);
+ VERIFY(tri_ret, FALSE, "H5Iis_valid");
+ if (tri_ret != FALSE)
+ goto out;
+
+ return 0;
+
+out:
+ /* Don't attempt to close dtype as we don't know the exact state of the
+ * reference counts. Every state in this function will be automatically
+ * closed at library exit anyways, as internal count is never > 1.
+ */
+ return -1;
+}
+
+
/* Test boundary cases with lots of types */
/* Type IDs range from H5I_NTYPES to MAX_NUM_TYPES. The system will assign */
@@ -418,8 +495,9 @@ out:
void test_ids(void)
{
- basic_id_test();
- id_predefined_test();
- test_id_type_list();
+ if (basic_id_test() < 0) TestErrPrintf("Basic ID test failed\n");
+ if (id_predefined_test() < 0) TestErrPrintf("Predefined ID type test failed\n");
+ if (test_is_valid() < 0) TestErrPrintf("H5Iis_valid test failed\n");
+ if (test_id_type_list() < 0) TestErrPrintf("ID type list test failed\n");
}