summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Young <dyoung@hdfgroup.org>2020-02-17 16:46:52 (GMT)
committerDavid Young <dyoung@hdfgroup.org>2020-02-17 16:46:52 (GMT)
commitfa2b89c6b0c894915f12a1df594ef8c427adbc2d (patch)
treefea728f0380438d459ba7c785e3d66da6b1ee4ce
parentddf139aed55ea130eebff56d5385351a01d46508 (diff)
parent3f903a441ad84001ea66589728bd8b036b6fdfca (diff)
downloadhdf5-fa2b89c6b0c894915f12a1df594ef8c427adbc2d.zip
hdf5-fa2b89c6b0c894915f12a1df594ef8c427adbc2d.tar.gz
hdf5-fa2b89c6b0c894915f12a1df594ef8c427adbc2d.tar.bz2
Merge pull request #2325 in HDFFV/hdf5 from ~DYOUNG/werror:h5t_copy to develop
Merged per discussion with Elena. * commit '3f903a441ad84001ea66589728bd8b036b6fdfca': Take out the temporary performance tests. Make calls through a function pointer. Use the same number of arguments, always. Increase iterations, provide a baseline for no-op, simplify the overhead case a bit. Temporarily add some code that measures the time to run the simplest possible H5T__copy_all()-like routine 10 million times and then measures the version with FUNC_ENTER_STATIC/_LEAVE_NOAPI and a HGOTO_ERROR() statement. H5T_copy() constification plus Quincey's contributions.
-rw-r--r--src/H5Aint.c6
-rw-r--r--src/H5Dint.c4
-rw-r--r--src/H5Fmount.c2
-rw-r--r--src/H5Gint.c2
-rw-r--r--src/H5Gobj.c2
-rw-r--r--src/H5Gtraverse.c2
-rw-r--r--src/H5L.c4
-rw-r--r--src/H5Oint.c101
-rw-r--r--src/H5Oprivate.h2
-rw-r--r--src/H5T.c444
-rw-r--r--src/H5Tcommit.c6
-rw-r--r--src/H5Tcompound.c87
-rw-r--r--src/H5Tnative.c2
-rw-r--r--src/H5Tprivate.h6
-rw-r--r--src/H5Znbit.c4
15 files changed, 480 insertions, 194 deletions
diff --git a/src/H5Aint.c b/src/H5Aint.c
index fc5ea34..1a74abe 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -224,7 +224,7 @@ H5A__create(const H5G_loc_t *loc, const char *attr_name, const H5T_t *type,
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set version of dataspace")
/* Copy the object header information */
- if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&(attr->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to copy entry")
/* Deep copy of the group hierarchy path */
@@ -390,7 +390,7 @@ H5A__open_common(const H5G_loc_t *loc, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
/* Deep copy of the symbol table entry */
- if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&(attr->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Deep copy of the group hier. path */
@@ -909,7 +909,7 @@ H5A__get_type(H5A_t *attr)
* reopen the type before returning it to the user. Make the type
* read-only.
*/
- if (NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN)))
+ if (NULL == (dt = H5T_copy_reopen(attr->shared->dt)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to copy datatype")
/* Mark any datatypes as being in memory now */
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 0d67fd0..1624f7b 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -1534,7 +1534,7 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Shallow copy (take ownership) of the object location object */
- if(H5O_loc_copy(&(dataset->oloc), loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&(dataset->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy object location")
/* Shallow copy (take ownership) of the group hier. path */
@@ -3881,7 +3881,7 @@ H5D__get_type(const H5D_t *dset)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer")
/* Copy the dataset's datatype */
- if(NULL == (dt = H5T_copy(dset->shared->type, H5T_COPY_REOPEN)))
+ if(NULL == (dt = H5T_copy_reopen(dset->shared->type)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype")
/* Mark any datatypes as being in memory now */
diff --git a/src/H5Fmount.c b/src/H5Fmount.c
index 13d95aa..5e6b899 100644
--- a/src/H5Fmount.c
+++ b/src/H5Fmount.c
@@ -766,7 +766,7 @@ H5F_traverse_mount(H5O_loc_t *oloc/*in,out*/)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "unable to free object location")
/* Copy the entry for the root group */
- if(H5O_loc_copy(oloc, mnt_oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(oloc, mnt_oloc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
/* In case the shared root group info points to a different file handle
diff --git a/src/H5Gint.c b/src/H5Gint.c
index e0b8bd7..a3849a6 100644
--- a/src/H5Gint.c
+++ b/src/H5Gint.c
@@ -336,7 +336,7 @@ H5G_open(const H5G_loc_t *loc)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group")
/* Shallow copy (take ownership) of the group location object */
- if(H5O_loc_copy(&(grp->oloc), loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&(grp->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy object location")
if(H5G_name_copy(&(grp->path), loc->path, H5_COPY_SHALLOW) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy path")
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 15dbd79..1892182 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -738,7 +738,7 @@ H5G__obj_info(const H5O_loc_t *oloc, H5G_info_t *grp_info)
H5G_loc_reset(&grp_loc);
/* Deep copy (duplicate) of the group location object */
- if(H5O_loc_copy(&grp_oloc, (H5O_loc_t *)oloc, H5_COPY_DEEP) < 0) /* (Casting away const OK - QAK) */
+ if(H5O_loc_copy_deep(&grp_oloc, oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy object location")
/* Open the group */
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index 7482e27..0f27880 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -132,7 +132,7 @@ H5G__traverse_slink_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNU
} /* end if */
else {
/* Copy new location information for resolved object */
- H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP);
+ H5O_loc_copy_deep(udata->obj_loc->oloc, obj_loc->oloc);
/* Indicate that the object exists */
udata->exists = TRUE;
diff --git a/src/H5L.c b/src/H5L.c
index 0d5bc02..47e29c0 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -1910,7 +1910,7 @@ H5L__link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t H5_ATT
* copy and wipe out grp_loc)
*/
H5G_name_reset(&temp_path);
- if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&temp_oloc, grp_loc->oloc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy object location")
temp_loc.oloc = &temp_oloc;
@@ -2695,7 +2695,7 @@ H5L__move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
* copy and wipe out grp_loc)
*/
H5G_name_reset(&temp_path);
- if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&temp_oloc, grp_loc->oloc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy object location")
temp_loc.oloc = &temp_oloc;
diff --git a/src/H5Oint.c b/src/H5Oint.c
index d5a3a71..04220af 100644
--- a/src/H5Oint.c
+++ b/src/H5Oint.c
@@ -1913,27 +1913,19 @@ H5O_loc_reset(H5O_loc_t *loc)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_loc_reset() */
-
+
/*-------------------------------------------------------------------------
* Function: H5O_loc_copy
*
- * Purpose: Copy object location information
+ * Purpose: Copy object location information, according to the depth.
*
* Return: Success: Non-negative
- * Failure: Negative
+ * Failure: Negative
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Monday, September 19, 2005
*
- * Notes: 'depth' parameter determines how much of the group entry
- * structure we want to copy. The values are:
- * H5_COPY_SHALLOW - Copy all the field values from the source
- * to the destination, but not copying objects pointed to.
- * (Destination "takes ownership" of objects pointed to)
- * H5_COPY_DEEP - Copy all the fields from the source to
- * the destination, deep copying objects pointed to.
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1946,25 +1938,88 @@ H5O_loc_copy(H5O_loc_t *dst, H5O_loc_t *src, H5_copy_depth_t depth)
HDassert(dst);
HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP);
+ /* Invoke correct routine */
+ if(depth == H5_COPY_SHALLOW)
+ H5O_loc_copy_shallow(dst, src);
+ else
+ H5O_loc_copy_deep(dst, src);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_copy_shallow
+ *
+ * Purpose: Shallow copy object location information. Copies all the field
+ * values from the source to the destination, but not copying
+ * objects pointed to. (i.e. destination "takes ownership" of
+ * objects pointed to)
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_copy_shallow(H5O_loc_t *dst, H5O_loc_t *src)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check arguments */
+ HDassert(src);
+ HDassert(dst);
+
/* Copy the top level information */
H5MM_memcpy(dst, src, sizeof(H5O_loc_t));
- /* Deep copy the names */
- if(depth == H5_COPY_DEEP) {
- /* If the original entry was holding open the file, this one should
- * hold it open, too.
- */
- if(src->holding_file)
- H5F_INCR_NOPEN_OBJS(dst->file);
- }
- else if(depth == H5_COPY_SHALLOW) {
- H5O_loc_reset(src);
- }
+ /* Reset the source location, as the destination 'owns' it now */
+ H5O_loc_reset(src);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5O_loc_copy() */
+} /* end H5O_loc_copy_shallow() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_copy_deep
+ *
+ * Purpose: Deep copy object location information. Copies all the fields
+ * from the source to the destination, deep copying objects
+ * pointed to.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_copy_deep(H5O_loc_t *dst, const H5O_loc_t *src)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check arguments */
+ HDassert(src);
+ HDassert(dst);
+
+ /* Copy the top level information */
+ H5MM_memcpy(dst, src, sizeof(H5O_loc_t));
+
+ /* If the original entry was holding open the file, this one should
+ * hold it open, too.
+ */
+ if(src->holding_file)
+ H5F_INCR_NOPEN_OBJS(dst->file);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_copy_deep() */
+
/*-------------------------------------------------------------------------
* Function: H5O_loc_hold_file
*
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 52a72b2..ceaa96d 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -997,6 +997,8 @@ H5_DLL herr_t H5O_debug(H5F_t *f, haddr_t addr, FILE * stream, int indent,
/* These functions operate on object locations */
H5_DLL herr_t H5O_loc_reset(H5O_loc_t *loc);
H5_DLL herr_t H5O_loc_copy(H5O_loc_t *dst, H5O_loc_t *src, H5_copy_depth_t depth);
+H5_DLL herr_t H5O_loc_copy_shallow(H5O_loc_t *dst, H5O_loc_t *src);
+H5_DLL herr_t H5O_loc_copy_deep(H5O_loc_t *dst, const H5O_loc_t *src);
H5_DLL herr_t H5O_loc_hold_file(H5O_loc_t *loc);
H5_DLL herr_t H5O_loc_free(H5O_loc_t *loc);
H5_DLL H5O_loc_t *H5O_get_loc(hid_t id);
diff --git a/src/H5T.c b/src/H5T.c
index f1c2dbb..5d3c4a1 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -301,6 +301,9 @@
/* Local Typedefs */
/******************/
+/* Typedef for recursive const-correct datatype copying routines */
+typedef H5T_t *(*H5T_copy_func_t)(H5T_t *old_dt);
+
/********************/
/* Local Prototypes */
@@ -313,6 +316,11 @@ static herr_t H5T__set_size(H5T_t *dt, size_t size);
static herr_t H5T__close_cb(H5T_t *dt);
static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_func_t *conv);
static hbool_t H5T__detect_vlen_ref(const H5T_t *dt);
+static H5T_t *H5T__initiate_copy(const H5T_t *old_dt);
+static H5T_t *H5T__copy_transient(H5T_t *old_dt);
+static H5T_t *H5T__copy_all(H5T_t *old_dt);
+static herr_t H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt,
+ H5T_shared_t *reopened_fo, hbool_t set_memory_type, H5T_copy_func_t copyfn);
/*****************************/
@@ -3304,132 +3312,152 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__create() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5T_copy
+ * Function: H5T__initiate_copy
*
- * Purpose: Copies datatype OLD_DT. The resulting data type is not
- * locked and is a transient type.
+ * Purpose: Allocates datatype structures, copies core fields, and initializes
+ * VOL fields.
*
* Return: Success: Pointer to a new copy of the OLD_DT argument.
- *
* Failure: NULL
*
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
+ * Note: Common code for both H5T_copy and H5T_copy_reopen, as part of
+ * the const-correct datatype copying routines.
+ *
+ * Programmer: David Young
+ * January 18, 2020
*
*-------------------------------------------------------------------------
*/
-H5T_t *
-H5T_copy(H5T_t *old_dt, H5T_copy_t method)
+static H5T_t *
+H5T__initiate_copy(const H5T_t *old_dt)
{
- H5T_t *new_dt = NULL, *tmp = NULL;
- H5T_shared_t *reopened_fo = NULL;
- unsigned i;
- char *s;
- H5T_t *ret_value = NULL; /* Return value */
-
- FUNC_ENTER_NOAPI(NULL)
+ H5T_t *new_dt = NULL; /* Copy of datatype */
+ H5T_t *ret_value = NULL; /* Return value */
- /* check args */
- HDassert(old_dt);
+ FUNC_ENTER_STATIC
/* Allocate space */
if(NULL == (new_dt = H5FL_MALLOC(H5T_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, NULL, "H5T_t memory allocation failed")
if(NULL == (new_dt->shared = H5FL_MALLOC(H5T_shared_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, NULL, "H5T_shared_t memory allocation failed")
- /* Copy shared information (entry information is copied last) */
+ /* Copy shared information */
*(new_dt->shared) = *(old_dt->shared);
- /* No VOL object */
+ /* Reset VOL fields */
new_dt->vol_obj = NULL;
-
- /* No owned VOL object */
new_dt->shared->owned_vol_obj = NULL;
- /* Check what sort of copy we are making */
- switch (method) {
- case H5T_COPY_TRANSIENT:
- /*
- * Return an unlocked transient type.
- */
- new_dt->shared->state = H5T_STATE_TRANSIENT;
- break;
+ /* Set return value */
+ ret_value = new_dt;
- case H5T_COPY_ALL:
- /*
- * Return a transient type (locked or unlocked) or an unopened named
- * type. Immutable transient types are degraded to read-only.
- */
- if(H5T_STATE_OPEN==old_dt->shared->state)
- new_dt->shared->state = H5T_STATE_NAMED;
- else if(H5T_STATE_IMMUTABLE==old_dt->shared->state)
- new_dt->shared->state = H5T_STATE_RDONLY;
- break;
+done:
+ if(ret_value == NULL)
+ if(new_dt) {
+ if(new_dt->shared)
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ new_dt = H5FL_FREE(H5T_t, new_dt);
+ } /* end if */
- case H5T_COPY_REOPEN:
- /*
- * Return a transient type (locked or unlocked) or an opened named
- * type. Immutable transient types are degraded to read-only.
- */
- if(old_dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
- /* Check if the object is already open */
- if(NULL == (reopened_fo = (H5T_shared_t *)H5FO_opened(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr))) {
- /* Clear any errors from H5FO_opened() */
- H5E_clear_stack(NULL);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__initiate_copy() */
- /* Open named datatype again */
- if(H5O_open(&old_dt->oloc) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reopen named data type")
+
+/*-------------------------------------------------------------------------
+ * Function: H5T__copy_transient
+ *
+ * Purpose: Part of recursive framework for const-correct datatype copying.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5T__copy_transient(H5T_t *old_dt)
+{
+ H5T_t *ret_value = NULL; /* Return value */
- /* Insert opened named datatype into opened object list for the file */
- if(H5FO_insert(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr, new_dt->shared, FALSE)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, NULL, "can't insert datatype into list of open objects")
+ FUNC_ENTER_STATIC
- /* Increment object count for the object in the top file */
- if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+ /* Copy datatype, with correct method */
+ if(NULL == (ret_value = H5T_copy(old_dt, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't make 'transient' copy of datatype")
- new_dt->shared->fo_count = 1;
- } /* end if */
- else {
- /* The object is already open. Free the H5T_shared_t struct
- * we had been using and use the one that already exists.
- * Not terribly efficient. */
- new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
- new_dt->shared = reopened_fo;
-
- reopened_fo->fo_count++;
-
- /* Check if the object has been opened through the top file yet */
- if(H5FO_top_count(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) == 0) {
- /* Open the object through this top file */
- if(H5O_open(&old_dt->oloc) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
- } /* end if */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__copy_transient() */
- /* Increment object count for the object in the top file */
- if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
- } /* end else */
- new_dt->shared->state = H5T_STATE_OPEN;
- }
- else if(H5T_STATE_IMMUTABLE == old_dt->shared->state) {
- new_dt->shared->state = H5T_STATE_RDONLY;
- }
- break;
- default:
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "invalid copy method type")
- } /* end switch */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T__copy_all
+ *
+ * Purpose: Part of recursive framework for const-correct datatype copying.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5T__copy_all(H5T_t *old_dt)
+{
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Copy datatype, with correct method */
+ if(NULL == (ret_value = H5T_copy(old_dt, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't make 'all' copy of datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__copy_transient() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T__complete_copy
+ *
+ * Purpose: Completes copying datatype fields, as part of the recursive
+ * const-correct datatype copy routines.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Note: Common code for both H5T_copy and H5T_copy_reopen.
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt, H5T_shared_t *reopened_fo,
+ hbool_t set_memory_type, H5T_copy_func_t copyfn)
+{
+ H5T_t *tmp = NULL; /* Temporary copy of compound field's datatype */
+ char *s; /* Temporary copy of compound field name / enum value name */
+ unsigned i; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
/* Update fields in the new struct, if we aren't sharing an already opened
* committed datatype */
if(!reopened_fo) {
/* Copy parent information */
if(old_dt->shared->parent)
- new_dt->shared->parent = H5T_copy(old_dt->shared->parent, method);
+ if(NULL == (new_dt->shared->parent = (*copyfn)(old_dt->shared->parent)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy datatype's parent type")
switch(new_dt->shared->type) {
case H5T_COMPOUND:
@@ -3443,10 +3471,8 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
*/
/* Only malloc if space has been allocated for members - NAF */
if(new_dt->shared->u.compnd.nalloc > 0) {
- new_dt->shared->u.compnd.memb =
- (H5T_cmemb_t *)H5MM_malloc(new_dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t));
- if (NULL == new_dt->shared->u.compnd.memb)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(NULL == (new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed")
H5MM_memcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb,
new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t));
@@ -3456,15 +3482,17 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
unsigned j;
int old_match;
- s = new_dt->shared->u.compnd.memb[i].name;
- new_dt->shared->u.compnd.memb[i].name = H5MM_xstrdup(s);
- tmp = H5T_copy (old_dt->shared->u.compnd.memb[i].type, method);
+ if(NULL == (s = H5MM_xstrdup(new_dt->shared->u.compnd.memb[i].name)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy string for compound field's name")
+ new_dt->shared->u.compnd.memb[i].name = s;
+ if(NULL == (tmp = (*copyfn)(old_dt->shared->u.compnd.memb[i].type)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy compound field's datatype")
new_dt->shared->u.compnd.memb[i].type = tmp;
HDassert(tmp != NULL);
/* Range check against compound member's offset */
- if ((accum_change < 0) && ((ssize_t) new_dt->shared->u.compnd.memb[i].offset < accum_change))
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, NULL, "invalid field size in datatype")
+ if((accum_change < 0) && ((ssize_t) new_dt->shared->u.compnd.memb[i].offset < accum_change))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid field size in datatype")
/* Apply the accumulated size change to the offset of the field */
new_dt->shared->u.compnd.memb[i].offset += (size_t) accum_change;
@@ -3479,7 +3507,7 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
/* check if we couldn't find a match */
if(old_match < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "fields in datatype corrupted")
} /* end if */
else
old_match = (int) i;
@@ -3494,8 +3522,8 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
} /* end for */
/* Range check against datatype size */
- if ((accum_change < 0) && ((ssize_t) new_dt->shared->size < accum_change))
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, NULL, "invalid field size in datatype")
+ if((accum_change < 0) && ((ssize_t) new_dt->shared->size < accum_change))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid field size in datatype")
/* Apply the accumulated size change to the size of the compound struct */
new_dt->shared->size += (size_t) accum_change;
@@ -3508,27 +3536,25 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
* of each new member with copied values. That is, H5T_copy() is a
* deep copy.
*/
- new_dt->shared->u.enumer.name =
- (char **)H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char*));
- new_dt->shared->u.enumer.value =
- (uint8_t *)H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size);
- if(NULL == new_dt->shared->u.enumer.value)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(NULL == (new_dt->shared->u.enumer.name = H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char*))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "enam name array memory allocation failed")
+ if(NULL == (new_dt->shared->u.enumer.value = H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "enam value array memory allocation failed")
H5MM_memcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value,
new_dt->shared->u.enumer.nmembs * new_dt->shared->size);
for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) {
- s = old_dt->shared->u.enumer.name[i];
- new_dt->shared->u.enumer.name[i] = H5MM_xstrdup(s);
+ if(NULL == (s = H5MM_xstrdup(old_dt->shared->u.enumer.name[i])))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy string for enum value's name")
+ new_dt->shared->u.enumer.name[i] = s;
} /* end for */
break;
case H5T_VLEN:
case H5T_REFERENCE:
- if(method == H5T_COPY_TRANSIENT || method == H5T_COPY_REOPEN) {
+ if(set_memory_type)
/* H5T_copy converts any type into a memory type */
if(H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
- } /* end if */
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
break;
case H5T_OPAQUE:
@@ -3540,7 +3566,7 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
case H5T_ARRAY:
/* Re-compute the array's size, in case it's base type changed size */
- new_dt->shared->size=new_dt->shared->u.array.nelem*new_dt->shared->parent->shared->size;
+ new_dt->shared->size = new_dt->shared->u.array.nelem * new_dt->shared->parent->shared->size;
break;
case H5T_NO_CLASS:
@@ -3559,15 +3585,15 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
* type and the new type is also named.
*/
if(H5O_loc_reset(&new_dt->oloc) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to initialize location")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, FAIL, "unable to initialize location")
if(H5G_name_reset(&new_dt->path) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reset path")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to reset path")
if(new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
- if(H5O_loc_copy(&(new_dt->oloc), &(old_dt->oloc), H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
+ if(H5O_loc_copy_deep(&(new_dt->oloc), &(old_dt->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy object location")
if(H5G_name_copy(&(new_dt->path), &(old_dt->path), H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to copy path")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy path")
} /* end if */
/* Copy shared location information if the new type is named or if it is
@@ -3576,28 +3602,194 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
if((old_dt->sh_loc.type == H5O_SHARE_TYPE_SOHM || old_dt->sh_loc.type == H5O_SHARE_TYPE_HERE) ||
new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
if(H5O_set_shared(&(new_dt->sh_loc), &(old_dt->sh_loc)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy shared information")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy shared information")
} /* end if */
else
/* Reset shared component info */
H5O_msg_reset_share(H5O_DTYPE_ID, new_dt);
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__complete_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_copy
+ *
+ * Purpose: Copies datatype OLD_DT. The resulting data type is not
+ * locked and is a transient type.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
+{
+ H5T_t *new_dt = NULL; /* New datatype */
+ H5T_copy_func_t copyfn; /* Pointer to correct copy routine */
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* check args */
+ HDassert(old_dt);
+
+ /* Allocate and copy core datatype information */
+ if(NULL == (new_dt = H5T__initiate_copy(old_dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy core datatype info")
+
+ /* Check what sort of copy we are making */
+ switch (method) {
+ case H5T_COPY_TRANSIENT:
+ /*
+ * Return an unlocked transient type.
+ */
+ new_dt->shared->state = H5T_STATE_TRANSIENT;
+ copyfn = H5T__copy_transient;
+ break;
+
+ case H5T_COPY_ALL:
+ /*
+ * Return a transient type (locked or unlocked) or an unopened named
+ * type. Immutable transient types are degraded to read-only.
+ */
+ if(H5T_STATE_OPEN==old_dt->shared->state)
+ new_dt->shared->state = H5T_STATE_NAMED;
+ else if(H5T_STATE_IMMUTABLE==old_dt->shared->state)
+ new_dt->shared->state = H5T_STATE_RDONLY;
+ copyfn = H5T__copy_all;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "invalid copy method type")
+ } /* end switch */
+
+ /* Finish making the copy of the datatype */
+ if(H5T__complete_copy(new_dt, old_dt, NULL, (method == H5T_COPY_TRANSIENT), copyfn) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't complete datatype initialization")
+
/* Set return value */
ret_value = new_dt;
done:
- if(ret_value == NULL) {
+ if(ret_value == NULL)
if(new_dt) {
- if(new_dt->shared)
- new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ HDassert(new_dt->shared);
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
new_dt = H5FL_FREE(H5T_t, new_dt);
} /* end if */
- } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_copy() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_copy_reopen
+ *
+ * Purpose: Copy a datatype, possibly reopening a named datatype, as part
+ * the const-correct datatype copying routines.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5T_copy_reopen(H5T_t *old_dt)
+{
+ H5T_t *new_dt = NULL; /* New datatype */
+ H5T_shared_t *reopened_fo = NULL; /* Pointer to reopened existing named datatype */
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* check args */
+ HDassert(old_dt);
+
+ /* Allocate and copy core datatype information */
+ if(NULL == (new_dt = H5T__initiate_copy(old_dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy core datatype info")
+
+ /*
+ * Return a transient type (locked or unlocked) or an opened named
+ * type. Immutable transient types are degraded to read-only.
+ */
+ if(old_dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
+ /* Check if the object is already open */
+ if(NULL == (reopened_fo = (H5T_shared_t *)H5FO_opened(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr))) {
+ /* Clear any errors from H5FO_opened() */
+ H5E_clear_stack(NULL);
+
+ /* Open named datatype again */
+ if(H5O_open(&old_dt->oloc) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reopen named data type")
+
+ /* Insert opened named datatype into opened object list for the file */
+ if(H5FO_insert(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr, new_dt->shared, FALSE)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, NULL, "can't insert datatype into list of open objects")
+
+ /* Increment object count for the object in the top file */
+ if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+
+ new_dt->shared->fo_count = 1;
+ } /* end if */
+ else {
+ /* The object is already open. Free the H5T_shared_t struct
+ * we had been using and use the one that already exists.
+ * Not terribly efficient. */
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ new_dt->shared = reopened_fo;
+
+ reopened_fo->fo_count++;
+
+ /* Check if the object has been opened through the top file yet */
+ if(H5FO_top_count(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) == 0) {
+ /* Open the object through this top file */
+ if(H5O_open(&old_dt->oloc) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
+ } /* end if */
+
+ /* Increment object count for the object in the top file */
+ if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+ } /* end else */
+
+ /* Set state for new datatype */
+ new_dt->shared->state = H5T_STATE_OPEN;
+ } /* end if */
+ else
+ /* Downgrade immutable datatypes to read-only */
+ if(H5T_STATE_IMMUTABLE == old_dt->shared->state)
+ new_dt->shared->state = H5T_STATE_RDONLY;
+
+ /* Finish making the copy of the datatype */
+ if(H5T__complete_copy(new_dt, old_dt, reopened_fo, TRUE, H5T_copy_reopen) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't complete datatype initialization")
+
+ /* Set return value */
+ ret_value = new_dt;
+
+done:
+ if(ret_value == NULL)
+ if(new_dt) {
+ HDassert(new_dt->shared);
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ new_dt = H5FL_FREE(H5T_t, new_dt);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_copy_reopen() */
+
/*-------------------------------------------------------------------------
* Function: H5T_lock
*
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index 1b922d5..7d26af3 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -446,7 +446,7 @@ H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message")
/* Copy the new object header's location into the datatype, taking ownership of it */
- if(H5O_loc_copy(&(type->oloc), &temp_oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&(type->oloc), &temp_oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location")
if(H5G_name_copy(&(type->path), &temp_path, H5_COPY_SHALLOW) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location")
@@ -943,7 +943,7 @@ H5T_open(const H5G_loc_t *loc)
#endif /* H5_USING_MEMCHECKER */
/* Shallow copy (take ownership) of the object location object */
- if(H5O_loc_copy(&dt->oloc, loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&dt->oloc, loc->oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
/* Shallow copy (take ownership) of the group hier. path */
@@ -1033,7 +1033,7 @@ H5T__open_oid(const H5G_loc_t *loc)
dt->shared->state = H5T_STATE_OPEN;
/* Shallow copy (take ownership) of the object location object */
- if(H5O_loc_copy(&dt->oloc, loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&dt->oloc, loc->oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
/* Shallow copy (take ownership) of the group hier. path */
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index d4f1008..f4a9e04 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -51,8 +51,9 @@
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5T_pack(const H5T_t *dt);
-static htri_t H5T_is_packed(const H5T_t *dt);
+static herr_t H5T__pack(const H5T_t *dt);
+static htri_t H5T__is_packed(const H5T_t *dt);
+static H5T_t *H5T__reopen_member_type(const H5T_t *dt, unsigned membno);
/*********************/
@@ -226,7 +227,7 @@ H5Tget_member_type(hid_t type_id, unsigned membno)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid member number")
/* Retrieve the datatype for the member */
- if(NULL == (memb_dt = H5T_get_member_type(dt, membno, H5T_COPY_REOPEN)))
+ if(NULL == (memb_dt = H5T__reopen_member_type(dt, membno)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5I_INVALID_HID, "unable to retrieve member type")
/* Get an ID for the datatype */
@@ -245,8 +246,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5T_get_member_type
*
- * Purpose: Private function for H5Tget_member_type. Returns the data
- * type of the specified member.
+ * Purpose: Returns a copy of the data type of the specified member.
*
* Return: Success: A copy of the member datatype;
* modifying the returned datatype does not
@@ -260,18 +260,19 @@ done:
*-------------------------------------------------------------------------
*/
H5T_t *
-H5T_get_member_type(const H5T_t *dt, unsigned membno, H5T_copy_t method)
+H5T_get_member_type(const H5T_t *dt, unsigned membno)
{
H5T_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
+ /* Sanity checks */
HDassert(dt);
HDassert(membno < dt->shared->u.compnd.nmembs);
- /* Copy datatype into an atom */
- if(NULL == (ret_value = H5T_copy(dt->shared->u.compnd.memb[membno].type, method)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member datatype")
+ /* Copy datatype */
+ if(NULL == (ret_value = H5T_copy(dt->shared->u.compnd.memb[membno].type, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy member datatype")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -279,6 +280,43 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5T__reopen_member_type
+ *
+ * Purpose: Private function for H5Tget_member_type. Returns a re-opened
+ * copy of the data type of the specified member.
+ *
+ * Return: Success: A copy of the member datatype;
+ * modifying the returned datatype does not
+ * modify the member type.
+ *
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5T__reopen_member_type(const H5T_t *dt, unsigned membno)
+{
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(dt);
+ HDassert(membno < dt->shared->u.compnd.nmembs);
+
+ /* Copy datatype, possibly re-opening it */
+ if(NULL == (ret_value = H5T_copy_reopen(dt->shared->u.compnd.memb[membno].type)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to reopen member datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__reopen_member_type() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5T__get_member_size
*
* Purpose: Returns the size of the specified member.
@@ -387,7 +425,7 @@ H5Tpack(hid_t type_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype")
/* Pack */
- if(H5T_pack(dt) < 0)
+ if(H5T__pack(dt) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound datatype")
done:
@@ -493,7 +531,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5T_pack
+ * Function: H5T__pack
*
* Purpose: Recursively packs a compound datatype by removing padding
* bytes. This is done in place (that is, destructively).
@@ -506,17 +544,17 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5T_pack(const H5T_t *dt)
+H5T__pack(const H5T_t *dt)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
HDassert(dt);
if(H5T_detect_class(dt, H5T_COMPOUND, FALSE) > 0) {
/* If datatype has been packed, skip packing it and indicate success */
- if(TRUE == H5T_is_packed(dt))
+ if(TRUE == H5T__is_packed(dt))
HGOTO_DONE(SUCCEED)
/* Check for packing unmodifiable datatype */
@@ -524,7 +562,7 @@ H5T_pack(const H5T_t *dt)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is read-only")
if(dt->shared->parent) {
- if (H5T_pack(dt->shared->parent) < 0)
+ if(H5T__pack(dt->shared->parent) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack parent of datatype")
/* Adjust size of datatype appropriately */
@@ -539,7 +577,7 @@ H5T_pack(const H5T_t *dt)
/* Recursively pack the members */
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
- if(H5T_pack(dt->shared->u.compnd.memb[i].type) < 0)
+ if(H5T__pack(dt->shared->u.compnd.memb[i].type) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound datatype")
/* Update the member size */
@@ -552,7 +590,7 @@ H5T_pack(const H5T_t *dt)
for(i = 0, offset = 0; i < dt->shared->u.compnd.nmembs; i++) {
dt->shared->u.compnd.memb[i].offset = offset;
offset += dt->shared->u.compnd.memb[i].size;
- }
+ } /* end for */
/* Change total size */
dt->shared->size = MAX(1, offset);
@@ -564,11 +602,11 @@ H5T_pack(const H5T_t *dt)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T_pack() */
+} /* end H5T__pack() */
/*-------------------------------------------------------------------------
- * Function: H5T_is_packed
+ * Function: H5T__is_packed
*
* Purpose: Checks whether a datatype which is compound (or has compound
* components) is packed.
@@ -583,11 +621,11 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5T_is_packed(const H5T_t *dt)
+H5T__is_packed(const H5T_t *dt)
{
htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC_NOERR
HDassert(dt);
@@ -596,12 +634,11 @@ H5T_is_packed(const H5T_t *dt)
dt = dt->shared->parent;
/* If this is a compound datatype, check if it is packed */
- if(dt->shared->type == H5T_COMPOUND) {
+ if(dt->shared->type == H5T_COMPOUND)
ret_value = (htri_t)(dt->shared->u.compnd.packed);
- } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T_is_packed() */
+} /* end H5T__is_packed() */
/*-------------------------------------------------------------------------
@@ -638,7 +675,7 @@ H5T__update_packed(const H5T_t *dt)
/* Now check if all members are packed */
for(i = 0; i < dt->shared->u.compnd.nmembs; i++)
- if(!H5T_is_packed(dt->shared->u.compnd.memb[i].type)) {
+ if(!H5T__is_packed(dt->shared->u.compnd.memb[i].type)) {
dt->shared->u.compnd.packed = FALSE;
break;
} /* end if */
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index 8859102..357bb08 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -272,7 +272,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
/* Construct child compound type and retrieve a list of their IDs, offsets, total size, and alignment for compound type. */
for(u = 0; u < nmemb; u++) {
- if(NULL == (memb_type = H5T_get_member_type(dtype, u, H5T_COPY_TRANSIENT)))
+ if(NULL == (memb_type = H5T_get_member_type(dtype, u)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed")
if(NULL == (comp_mname[u] = H5T__get_member_name(dtype, u)))
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index d8e98af..e05bb4e 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -59,7 +59,6 @@ struct H5S_t;
typedef enum H5T_copy_t {
H5T_COPY_TRANSIENT,
H5T_COPY_ALL,
- H5T_COPY_REOPEN
} H5T_copy_t;
/* Location of datatype information */
@@ -109,7 +108,8 @@ H5_DLLVAR H5T_order_t H5T_native_order_g;
/* Private functions */
H5_DLL herr_t H5T_init(void);
-H5_DLL H5T_t *H5T_copy(H5T_t *old_dt, H5T_copy_t method);
+H5_DLL H5T_t *H5T_copy(const H5T_t *old_dt, H5T_copy_t method);
+H5_DLL H5T_t *H5T_copy_reopen(H5T_t *old_dt);
H5_DLL herr_t H5T_lock(H5T_t *dt, hbool_t immutable);
H5_DLL herr_t H5T_close(H5T_t *dt);
H5_DLL herr_t H5T_close_real(H5T_t *dt);
@@ -164,7 +164,7 @@ H5_DLL herr_t H5T_update_shared(H5T_t *type);
/* Field functions (for both compound & enumerated types) */
H5_DLL int H5T_get_nmembers(const H5T_t *dt);
-H5_DLL H5T_t *H5T_get_member_type(const H5T_t *dt, unsigned membno, H5T_copy_t method);
+H5_DLL H5T_t *H5T_get_member_type(const H5T_t *dt, unsigned membno);
H5_DLL size_t H5T_get_member_offset(const H5T_t *dt, unsigned membno);
/* Atomic functions */
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index fe0041c..2f79725 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -338,7 +338,7 @@ H5Z_calc_parms_compound(const H5T_t *type, size_t *cd_values_actual_nparms)
H5T_class_t dtype_member_class; /* Compound datatype's member datatype's class */
/* Get member datatype */
- if(NULL == (dtype_member = H5T_get_member_type(type, u, H5T_COPY_TRANSIENT)))
+ if(NULL == (dtype_member = H5T_get_member_type(type, u)))
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype")
/* Get member datatype's class */
@@ -695,7 +695,7 @@ H5Z_set_parms_compound(const H5T_t *type, unsigned *cd_values_index,
/* For each member, set parameters */
for(u = 0; u < nmembers; u++) {
/* Get member datatype */
- if(NULL == (dtype_member = H5T_get_member_type(type, u, H5T_COPY_TRANSIENT)))
+ if(NULL == (dtype_member = H5T_get_member_type(type, u)))
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype")
/* Get member datatype's class */