summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt4
-rw-r--r--src/H5A.c30
-rw-r--r--src/H5Apkg.h26
-rw-r--r--src/H5Aprivate.h32
-rw-r--r--src/H5Oainfo.c14
-rw-r--r--src/H5Oattr.c1
-rw-r--r--src/H5Oattribute.c5
-rw-r--r--src/H5Ocopy.c778
-rw-r--r--src/H5Odtype.c38
-rw-r--r--src/H5Oefl.c8
-rw-r--r--src/H5Ofill.c2
-rw-r--r--src/H5Olayout.c8
-rw-r--r--src/H5Olinfo.c16
-rw-r--r--src/H5Olink.c16
-rw-r--r--src/H5Omessage.c6
-rw-r--r--src/H5Opkg.h12
-rw-r--r--src/H5Opline.c1
-rw-r--r--src/H5Oprivate.h22
-rw-r--r--src/H5Opublic.h11
-rw-r--r--src/H5Osdspace.c1
-rw-r--r--src/H5Oshared.c17
-rw-r--r--src/H5Oshared.h21
-rw-r--r--src/H5Ostab.c18
-rw-r--r--src/H5Pdcpl.c2
-rw-r--r--src/H5Pocpypl.c443
-rw-r--r--src/H5Ppublic.h5
-rw-r--r--src/H5SM.c5
-rw-r--r--test/objcopy.c3221
28 files changed, 4621 insertions, 142 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 6c61597..58ad605 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -392,6 +392,10 @@ Bug Fixes since HDF5-1.8.0 release
2012/1/25. Issue 7756)
- Fixed a seg fault that could occur when shrinking a dataset with chunks
larger than 1 MB. (NAF - 2011/11/30 - HDFFV-7833)
+ - Fixed a bug that could cause file corruption when copying named
+ datatypes to a file using shared messages. (NAF - 2011/11/14)
+ - Fixed a bug that could cause H5Oget_info to return the wrong address
+ after copying a named datatype. (NAF - 2011/11/14)
- The library allowed the conversion of strings between ASCII and UTF8
(Issue 7582). We have corrected it to report an error under this
situation. (SLU - 2011/11/8)
diff --git a/src/H5A.c b/src/H5A.c
index cc6a7a5..63a908d 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -2523,6 +2523,36 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5A_type
+ *
+ * Purpose: Return the datatype for an attribute.
+ *
+ * Return: Success: Ptr to entry
+ * Failure: NULL
+ *
+ * Programmer: Neil Fortner
+ * Friday, November 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5A_type(const H5A_t *attr)
+{
+ H5T_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ HDassert(attr);
+
+ /* Set return value */
+ ret_value = attr->shared->dt;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_type() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Aexists
*
* Purpose: Checks if an attribute with a given name exists on an opened
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 20aa5b9..26c8dff 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -158,29 +158,6 @@ typedef struct {
H5A_t **attrs; /* Pointer to array of attribute pointers */
} H5A_attr_table_t;
-/* Attribute iteration operator for internal library callbacks */
-typedef herr_t (*H5A_lib_iterate_t)(const H5A_t *attr, void *op_data);
-
-/* Describe kind of callback to make for each attribute */
-typedef enum H5A_attr_iter_op_type_t {
-#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5A_ATTR_OP_APP, /* Application callback */
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5A_ATTR_OP_APP2, /* Revised application callback */
- H5A_ATTR_OP_LIB /* Library internal callback */
-} H5A_attr_iter_op_type_t;
-
-typedef struct H5A_attr_iter_op_t {
- H5A_attr_iter_op_type_t op_type;
- union {
-#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5A_operator1_t app_op; /* Application callback for each attribute */
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5A_operator2_t app_op2; /* Revised application callback for each attribute */
- H5A_lib_iterate_t lib_op; /* Library internal callback for each attribute */
- } u;
-} H5A_attr_iter_op_t;
-
/*****************************/
/* Package Private Variables */
@@ -268,9 +245,6 @@ H5_DLL herr_t H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id,
H5A_t *attr);
H5_DLL herr_t H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id,
const char *old_name, const char *new_name);
-H5_DLL herr_t H5O_attr_iterate(hid_t loc_id, hid_t dxpl_id, H5_index_t idx_type,
- H5_iter_order_t order, hsize_t skip, hsize_t *last_attr,
- const H5A_attr_iter_op_t *op, void *op_data);
H5_DLL herr_t H5O_attr_remove(const H5O_loc_t *loc, const char *name,
hid_t dxpl_id);
H5_DLL herr_t H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h
index 0c0e519..6646fa2 100644
--- a/src/H5Aprivate.h
+++ b/src/H5Aprivate.h
@@ -24,6 +24,8 @@
/* Private headers needed by this file */
#include "H5Gprivate.h" /* Groups */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Tprivate.h" /* Datatypes */
/**************************/
@@ -38,6 +40,29 @@
/* Forward references of package typedefs */
typedef struct H5A_t H5A_t;
+/* Attribute iteration operator for internal library callbacks */
+typedef herr_t (*H5A_lib_iterate_t)(const H5A_t *attr, void *op_data);
+
+/* Describe kind of callback to make for each attribute */
+typedef enum H5A_attr_iter_op_type_t {
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+ H5A_ATTR_OP_APP, /* Application callback */
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+ H5A_ATTR_OP_APP2, /* Revised application callback */
+ H5A_ATTR_OP_LIB /* Library internal callback */
+} H5A_attr_iter_op_type_t;
+
+typedef struct H5A_attr_iter_op_t {
+ H5A_attr_iter_op_type_t op_type;
+ union {
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+ H5A_operator1_t app_op; /* Application callback for each attribute */
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
+ H5A_operator2_t app_op2; /* Revised application callback for each attribute */
+ H5A_lib_iterate_t lib_op; /* Library internal callback for each attribute */
+ } u;
+} H5A_attr_iter_op_t;
+
/*****************************/
/* Library-private Variables */
@@ -51,6 +76,13 @@ typedef struct H5A_t H5A_t;
/* General attribute routines */
H5_DLL struct H5O_loc_t *H5A_oloc(H5A_t *attr);
H5_DLL H5G_name_t *H5A_nameof(H5A_t *attr);
+H5_DLL H5T_t *H5A_type(const H5A_t *attr);
+H5_DLL herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc,
+ hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
+ hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data);
+H5_DLL herr_t H5O_attr_iterate(hid_t loc_id, hid_t dxpl_id, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t skip, hsize_t *last_attr,
+ const H5A_attr_iter_op_t *op, void *op_data);
#endif /* _H5Aprivate_H */
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index ff4cc5d..b207ea2 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -46,11 +46,11 @@ static herr_t H5O_ainfo_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
static herr_t H5O_ainfo_pre_copy_file(H5F_t *file_src, const void *mesg_src,
hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
static void *H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata,
- hid_t dxpl_id);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
static herr_t H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc,
- const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
- H5O_copy_t *cpy_info);
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_ainfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -403,7 +403,8 @@ H5O_ainfo_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
*/
static void *
H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
{
H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src;
H5O_ainfo_t *ainfo_dst = NULL;
@@ -468,7 +469,8 @@ done:
*/
static herr_t
H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
- H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_ainfo_t *ainfo_src = (const H5O_ainfo_t *)mesg_src;
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 8cd243b..510d64f 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -61,6 +61,7 @@ static herr_t H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#define H5O_SHARED_COPY_FILE_REAL H5O_attr_copy_file
#define H5O_SHARED_POST_COPY_FILE H5O_attr_shared_post_copy_file
#define H5O_SHARED_POST_COPY_FILE_REAL H5O_attr_post_copy_file
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_attr_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_attr_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index fbfc140..5778dc1 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -135,9 +135,6 @@ typedef struct {
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc,
- hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
- hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data);
static htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr,
const char* name_to_open);
@@ -1260,7 +1257,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
H5_index_t idx_type, H5_iter_order_t order, hsize_t skip,
hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data)
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index e2d792a..7b812ec 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -34,6 +34,7 @@
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
+#include "H5Aprivate.h" /* Attributes */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
@@ -55,6 +56,20 @@
/* Local Typedefs */
/******************/
+/* Key object for skiplist of committed datatypes */
+typedef struct H5O_copy_search_comm_dt_key_t {
+ H5T_t *dt; /* Datatype */
+ unsigned long fileno; /* File number */
+} H5O_copy_search_comm_dt_key_t;
+
+/* Callback struct for building a list of committed datatypes */
+typedef struct H5O_copy_search_comm_dt_ud_t {
+ H5SL_t *dst_dt_list; /* Skip list of committed datatypes */
+ H5G_loc_t *dst_root_loc; /* Starting location for iteration */
+ H5O_loc_t obj_oloc; /* Object location (for attribute iteration callback) */
+ hid_t dxpl_id; /* Dataset transfer property list id */
+} H5O_copy_search_comm_dt_ud_t;
+
/********************/
/* Package Typedefs */
@@ -66,14 +81,23 @@
/********************/
static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
-static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
+static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type, void **udata);
-static herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option);
+static herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
+ hid_t dxpl_id, hid_t ocpypl_id);
static herr_t H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc,
const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id);
static herr_t H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id,
H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info);
+static herr_t H5O_copy_free_comm_dt_cb(void *item, void *key, void *op_data);
+static int H5O_copy_comm_dt_cmp(const void *dt1, const void *dt2);
+static herr_t H5O_copy_search_comm_dt_cb(hid_t group, const char *name,
+ const H5L_info_t *linfo, void *udata);
+static htri_t H5O_copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src,
+ H5O_loc_t *oloc_dst/*in, out*/, hid_t dxpl_id, H5O_copy_t *cpy_info);
+static herr_t H5O_copy_insert_comm_dt(H5F_t *file_src, H5O_t *oh_src,
+ H5O_loc_t *oloc_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+
/*********************/
/* Package Variables */
@@ -82,6 +106,12 @@ static herr_t H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id,
/* Declare a free list to manage the H5O_addr_map_t struct */
H5FL_DEFINE(H5O_addr_map_t);
+/* Declare a free list to manage the H5O_copy_search_comm_dt_key_t struct */
+H5FL_DEFINE(H5O_copy_search_comm_dt_key_t);
+
+/* Declare a free list to manage haddr_t variables */
+H5FL_DEFINE(haddr_t);
+
/*****************************/
/* Library Private Variables */
@@ -292,8 +322,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type, void **udata)
+H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
+ hid_t dxpl_id, H5O_copy_t *cpy_info, H5O_type_t *obj_type,
+ void **udata /*out*/)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
H5O_t *oh_src = NULL; /* Object header for source object */
@@ -356,6 +387,53 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
(NULL == (cpy_udata = (obj_class->get_copy_file_udata)())))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to retrieve copy user data")
+ /* If we are merging committed datatypes, check for a match in the destination
+ * file now */
+ if(cpy_info->merge_comm_dt && obj_class->type == H5O_TYPE_NAMED_DATATYPE) {
+ unsigned long fileno_src; /* fileno for source file */
+ unsigned long fileno_dst; /* fileno for destination file */
+ htri_t merge; /* Whether we found a match in the destination file */
+
+ /* Check if the source and dest file are the same. If so, just return
+ * the source object address */
+ H5F_GET_FILENO(oloc_src->file, fileno_src);
+ H5F_GET_FILENO(oloc_dst->file, fileno_dst);
+ if(fileno_src == fileno_dst) {
+ merge = TRUE;
+ oloc_dst->addr = oloc_src->addr;
+ } /* end if */
+ else
+ /* Search for a matching committed datatype, building the list if
+ * necessary */
+ if((merge = H5O_copy_search_comm_dt(oloc_src->file, oh_src, oloc_dst, dxpl_id, cpy_info)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't search for matching committed datatype")
+
+ if(merge) {
+ /* Found a match, add to skip list and exit */
+ /* Allocate space for the address mapping of the object copied */
+ if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Insert the address mapping for the found object into the copied
+ * list */
+ addr_map->src_obj_pos.fileno = fileno_src;
+ addr_map->src_obj_pos.addr = oloc_src->addr;
+ addr_map->dst_addr = oloc_dst->addr;
+ addr_map->is_locked = TRUE; /* We've locked the object currently */
+ addr_map->inc_ref_count = 0; /* Start with no additional ref counts to add */
+ addr_map->obj_class = obj_class;
+ addr_map->udata = cpy_udata;
+
+ /* Insert into skip list */
+ if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0) {
+ addr_map = H5FL_FREE(H5O_addr_map_t, addr_map);
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ } /* end if */
+
+ HGOTO_DONE(SUCCEED)
+ } /* end if */
+ } /* end if */
+
/* Flush any dirty messages in source object header to update the header chunks */
if(H5O_flush_msgs(oloc_src->file, oh_src) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object header messages")
@@ -497,38 +575,33 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* copy this message into destination file */
if(copy_type->copy_file) {
- htri_t is_shared; /* Whether message is shared */
hbool_t recompute_size; /* Whether copy_file callback created a shared message */
+ unsigned mesg_flags; /* Message flags */
/* Decode the message if necessary. */
H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL)
+ /* Get destination message flags, and unset shared and shareable
+ * flags. mesg_dst->flags will contain the original flags for now.
+ */
+ mesg_flags = (unsigned)mesg_dst->flags & ~H5O_MSG_FLAG_SHARED
+ & ~H5O_MSG_FLAG_SHAREABLE;
+
/* Copy the source message */
recompute_size = FALSE;
- if((mesg_dst->native = H5O_msg_copy_file(copy_type,
- oloc_src->file, mesg_src->native, oloc_dst->file,
- &recompute_size, cpy_info, cpy_udata, dxpl_id)) == NULL)
+ if((mesg_dst->native = H5O_msg_copy_file(copy_type, oloc_src->file,
+ mesg_src->native, oloc_dst->file, &recompute_size,
+ &mesg_flags, cpy_info, cpy_udata, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
- /* Check if new message is shared */
- if((is_shared = H5O_msg_is_shared(copy_type->id, mesg_dst->native)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to query message's shared status")
-
- /* In being copied, the message may have become shared or stopped
- * being shared, set/unset its sharing flag.
+ /* Check if the sharing state changed, and recompute the size if so
*/
- if(is_shared && !(mesg_dst->flags & H5O_MSG_FLAG_SHARED)) {
- mesg_dst->flags |= H5O_MSG_FLAG_SHARED;
-
- /* Recompute message size (mesg_dst->native is really shared) */
- recompute_size = TRUE;
- } /* end if */
- else if(!is_shared && (mesg_dst->flags & H5O_MSG_FLAG_SHARED)) {
- mesg_dst->flags &= ~H5O_MSG_FLAG_SHARED;
-
- /* Recompute message size (msg_dest->native is no longer shared) */
+ if(!(mesg_flags & H5O_MSG_FLAG_SHARED)
+ != !(mesg_dst->flags & H5O_MSG_FLAG_SHARED))
recompute_size = TRUE;
- } /* end if */
+
+ /* Set destination message flags */
+ mesg_dst->flags = (uint8_t)mesg_flags;
/* Recompute message's size */
/* (its sharing status or one of its components (for attributes)
@@ -698,6 +771,13 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
oloc_dst->addr = addr_new;
+ /* If we are merging committed datatypes and this is a committed datatype, insert
+ * the copied datatype into the list of committed datatypes in the target file.
+ */
+ if(cpy_info->merge_comm_dt && obj_class->type == H5O_TYPE_NAMED_DATATYPE)
+ if(H5O_copy_insert_comm_dt(oloc_src->file, oh_src, oloc_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't insert committed datatype into destination list")
+
/* Allocate space for the address mapping of the object copied */
if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
@@ -713,8 +793,10 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
addr_map->udata = cpy_udata;
/* Insert into skip list */
- if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0)
+ if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0) {
+ addr_map = H5FL_FREE(H5O_addr_map_t, addr_map);
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ } /* end if */
/* "post copy" loop over messages, to fix up any messages which require a complete
* object header for destination object
@@ -743,17 +825,26 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(copy_type);
if(copy_type->post_copy_file && mesg_src->native) {
+ unsigned mesg_flags; /* Message flags */
+
/* Sanity check destination message */
HDassert(mesg_dst->type == mesg_src->type);
HDassert(mesg_dst->native);
+ /* Get destination message flags. mesg_dst->flags will contain the
+ * original flags for now. */
+ mesg_flags = (unsigned)mesg_dst->flags;
+
/* the object header is needed in the post copy for shared message */
cpy_info->oh_dst = oh_dst;
/* Perform "post copy" operation on message */
if((copy_type->post_copy_file)(oloc_src, mesg_src->native, oloc_dst,
- mesg_dst->native, dxpl_id, cpy_info) < 0)
+ mesg_dst->native, &mesg_flags, dxpl_id, cpy_info) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
+
+ /* Verify that the flags did not change */
+ HDassert(mesg_flags == (unsigned) mesg_dst->flags);
} /* end if */
} /* end for */
@@ -824,9 +915,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
+H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth,
- H5O_type_t *obj_type, void **udata)
+ H5O_type_t *obj_type, void **udata /*out*/)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
H5_obj_t src_obj_pos; /* Position of source object */
@@ -964,9 +1055,13 @@ H5O_copy_free_addrmap_cb(void *_item, void UNUSED *key, void UNUSED *op_data)
*/
static herr_t
H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option)
+ hid_t dxpl_id, hid_t ocpypl_id)
{
H5O_copy_t cpy_info; /* Information for copying object */
+ H5P_genplist_t *ocpy_plist; /* Object copy property list created */
+ H5O_copy_dtype_merge_list_t *dt_list = NULL; /* List of datatype merge suggestions */
+ H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
+ unsigned cpy_option = 0; /* Copy options */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
@@ -976,6 +1071,22 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(H5F_addr_defined(oloc_src->addr));
HDassert(oloc_dst->file);
+ /* Get the copy property list */
+ if(NULL == (ocpy_plist = (H5P_genplist_t *)H5I_object(ocpypl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* Retrieve the copy parameters */
+ if(H5P_get(ocpy_plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag")
+
+ /* Retrieve the marge committed datatype list */
+ if(H5P_get(ocpy_plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge committed datatype list")
+
+ /* Get callback info */
+ if(H5P_get(ocpy_plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info")
+
/* Convert copy flags into copy struct */
HDmemset(&cpy_info, 0, sizeof(H5O_copy_t));
if((cpy_option & H5O_COPY_SHALLOW_HIERARCHY_FLAG) > 0) {
@@ -995,9 +1106,18 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
cpy_info.copy_without_attr = TRUE;
if((cpy_option & H5O_COPY_PRESERVE_NULL_FLAG) > 0)
cpy_info.preserve_null = TRUE;
+ if((cpy_option & H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) > 0)
+ cpy_info.merge_comm_dt = TRUE;
+
+ /* Add dt_list to copy struct */
+ cpy_info.dst_dt_suggestion_list = dt_list;
+
+ /* Add set callback information */
+ cpy_info.mcdt_cb = cb_info.func;
+ cpy_info.mcdt_ud = cb_info.user_data;
/* Create a skip list to keep track of which objects are copied */
- if((cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ, NULL)) == NULL)
+ if(NULL == (cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ, NULL)))
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
@@ -1007,6 +1127,8 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
done:
if(cpy_info.map_list)
H5SL_destroy(cpy_info.map_list, H5O_copy_free_addrmap_cb, NULL);
+ if(cpy_info.dst_dt_list)
+ H5SL_destroy(cpy_info.dst_dt_list, H5O_copy_free_comm_dt_cb, NULL);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_copy_header() */
@@ -1028,14 +1150,12 @@ static herr_t
H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
hid_t ocpypl_id, hid_t lcpl_id)
{
- H5P_genplist_t *ocpy_plist=NULL; /* Object copy property list created */
- hid_t dxpl_id=H5AC_dxpl_id;
H5G_name_t new_path; /* Copied object group hier. path */
H5O_loc_t new_oloc; /* Copied object object location */
H5G_loc_t new_loc; /* Group location of object copied */
H5F_t *cached_dst_file; /* Cached destination file */
- hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */
- unsigned cpy_option = 0; /* Copy options */
+ hbool_t entry_inserted = FALSE; /* Flag to indicate that the new entry was inserted into a group */
+ hid_t dxpl_id = H5AC_dxpl_id; /* DXPL for operation */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -1046,14 +1166,6 @@ H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
HDassert(dst_loc->oloc->file);
HDassert(dst_name);
- /* Get the copy property list */
- if(NULL == (ocpy_plist = (H5P_genplist_t *)H5I_object(ocpypl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
-
- /* Retrieve the copy parameters */
- if(H5P_get(ocpy_plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag")
-
/* Set up copied object location to fill in */
new_loc.oloc = &new_oloc;
new_loc.path = &new_path;
@@ -1066,7 +1178,7 @@ H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
cached_dst_file = dst_loc->oloc->file;
/* Copy the object from the source file to the destination file */
- if(H5O_copy_header(src_loc->oloc, &new_oloc, dxpl_id, cpy_option) < 0)
+ if(H5O_copy_header(src_loc->oloc, &new_oloc, dxpl_id, ocpypl_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Patch dst_loc. Again, this can be removed once oloc's point to shared
@@ -1282,3 +1394,579 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_copy_expand_ref() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_free_comm_dt_cb
+ *
+ * Purpose: Frees the merge committed dt skip list key and object.
+ *
+ * Return: SUCCEED (never fails)
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_free_comm_dt_cb(void *item, void *_key, void UNUSED *op_data)
+{
+ haddr_t *addr = (haddr_t *)item;
+ H5O_copy_search_comm_dt_key_t *key = (H5O_copy_search_comm_dt_key_t *)_key;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(addr);
+ HDassert(key);
+ HDassert(key->dt);
+
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ addr = H5FL_FREE(haddr_t, addr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_copy_free_comm_dt_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_comm_dt_cmp
+ *
+ * Purpose: Skiplist callback used to compare 2 keys for the merge
+ * committed dt list. Mostly a wrapper for H5T_cmp.
+ *
+ * Return: 0 if key1 and key2 are equal.
+ * <0 if key1 is less than key2.
+ * >0 if key1 is greater than key2.
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5O_copy_comm_dt_cmp(const void *_key1, const void *_key2)
+{
+ const H5O_copy_search_comm_dt_key_t *key1 = (const H5O_copy_search_comm_dt_key_t *)_key1;
+ const H5O_copy_search_comm_dt_key_t *key2 = (const H5O_copy_search_comm_dt_key_t *)_key2;
+ int ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check fileno. It is unlikely to be different so check if they are equal
+ * first so only one comparison needs to be made. */
+ if(key1->fileno != key2->fileno) {
+ if(key1->fileno < key2->fileno)
+ HGOTO_DONE(-1)
+ if(key1->fileno > key2->fileno)
+ HGOTO_DONE(1)
+ } /* end if */
+
+ ret_value = H5T_cmp(key1->dt, key2->dt, FALSE);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_comm_dt_cmp */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt_attr_cb
+ *
+ * Purpose: Callback for H5O_attr_iterate_real from
+ * H5O_copy_search_comm_dt_check. Checks if the attribute's
+ * datatype is committed. If it is, adds it to the merge
+ * committed dt skiplist present in udata if it does not match
+ * any already present.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Nov 3 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_search_comm_dt_attr_cb(const H5A_t *attr, void *_udata)
+{
+ H5O_copy_search_comm_dt_ud_t *udata = (H5O_copy_search_comm_dt_ud_t *)_udata;
+ H5T_t *dt = NULL; /* Datatype */
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *addr = NULL; /* Destination address */
+ hbool_t obj_inserted = FALSE; /* Object inserted into skip list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(attr);
+ HDassert(udata);
+ HDassert(udata->dst_dt_list);
+ HDassert(H5F_addr_defined(udata->obj_oloc.addr));
+
+ /* Get attribute datatype */
+ if(NULL == (dt = H5A_type(attr)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get attribute datatype")
+
+ /* Check if the datatype is committed and search the skip list if so */
+ if(H5T_committed(dt)) {
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Copy datatype into key */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_copy(H5O_DTYPE_ID, dt, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy datatype message")
+
+ /* Get datatype object fileno */
+ H5F_GET_FILENO(udata->obj_oloc.file, key->fileno);
+
+ if(!H5SL_search(udata->dst_dt_list, key)) {
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = ((H5O_shared_t *)(key->dt))->u.loc.oh_addr;
+ if(H5SL_insert(udata->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ obj_inserted = TRUE;
+ } /* end if */
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(!obj_inserted) {
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+ if(addr) {
+ HDassert(ret_value < 0);
+ addr = H5FL_FREE(haddr_t, addr);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt_attr_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt_check
+ *
+ * Purpose: Check if the object at obj_oloc is or contains a reference
+ * to a committed datatype. If it does, adds it to the merge
+ * committed dt skiplist present in udata if it does not match
+ * any already present.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Nov 3 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc,
+ H5O_copy_search_comm_dt_ud_t *udata)
+{
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *addr = NULL; /* Destination address */
+ hbool_t obj_inserted = FALSE; /* Object inserted into skip list */
+ H5O_info_t oinfo; /* Object info */
+ H5A_attr_iter_op_t attr_op; /* Attribute iteration operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(obj_oloc);
+ HDassert(udata);
+ HDassert(udata->dst_dt_list);
+ HDassert(udata->dst_root_loc);
+
+ /* Get the object's info */
+ if(H5O_get_info(obj_oloc, udata->dxpl_id, TRUE, &oinfo) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info")
+
+ /* Check if the object is a datatype, a dataset using a committed
+ * datatype, or contains an attribute using a committed datatype */
+ if(oinfo.type == H5O_TYPE_NAMED_DATATYPE) {
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the destination datatype */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read(obj_oloc, H5O_DTYPE_ID, NULL, udata->dxpl_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Get destination object fileno */
+ H5F_GET_FILENO(obj_oloc->file, key->fileno);
+
+ /* Check if the datatype is already present in the skip list */
+ if(!H5SL_search(udata->dst_dt_list, key)) {
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = obj_oloc->addr;
+ if(H5SL_insert(udata->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ obj_inserted = TRUE;
+ } /* end if */
+ } /* end if */
+ else if(oinfo.type == H5O_TYPE_DATASET) {
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the destination datatype */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read(obj_oloc, H5O_DTYPE_ID, NULL, udata->dxpl_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Check if the datatype is committed and search the skip list if so
+ */
+ if(H5T_committed(key->dt)) {
+ /* Get datatype object fileno */
+ H5F_GET_FILENO(obj_oloc->file, key->fileno);
+
+ if(!H5SL_search(udata->dst_dt_list, key)) {
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = ((H5O_shared_t *)(key->dt))->u.loc.oh_addr;
+ if(H5SL_insert(udata->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ obj_inserted = TRUE;
+ } /* end if */
+ } /* end if */
+ } /* end else */
+
+ /* Search within attributes */
+ attr_op.op_type = H5A_ATTR_OP_LIB;
+ attr_op.u.lib_op = H5O_copy_search_comm_dt_attr_cb;
+ udata->obj_oloc.file = obj_oloc->file;
+ udata->obj_oloc.addr = obj_oloc->addr;
+ if(H5O_attr_iterate_real((hid_t)-1, obj_oloc, udata->dxpl_id, H5_INDEX_NAME, H5_ITER_NATIVE, 0, NULL, &attr_op, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "error iterating over attributes");
+
+done:
+ /* Release resources */
+ if(!obj_inserted) {
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+ if(addr) {
+ HDassert(ret_value < 0);
+ addr = H5FL_FREE(haddr_t, addr);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt_check */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt_cb
+ *
+ * Purpose: H5G_visit callback to add committed datatypes to the merge
+ * committed dt skiplist. Mostly a wrapper for
+ * H5O_copy_search_comm_dt_check.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_search_comm_dt_cb(hid_t UNUSED group, const char *name,
+ const H5L_info_t *linfo, void *_udata)
+{
+ H5O_copy_search_comm_dt_ud_t *udata = (H5O_copy_search_comm_dt_ud_t *)_udata; /* Skip list of dtypes in dest file */
+ H5G_loc_t obj_loc; /* Location of object */
+ H5O_loc_t obj_oloc; /* Object's object location */
+ H5G_name_t obj_path; /* Object's group hier. path */
+ hbool_t obj_found = FALSE; /* Object at 'name' found */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(name);
+ HDassert(linfo);
+ HDassert(udata);
+ HDassert(udata->dst_dt_list);
+ HDassert(udata->dst_root_loc);
+
+ /* Check if this is a hard link */
+ if(linfo->type == H5L_TYPE_HARD) {
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Find the object */
+ if(H5G_loc_find(udata->dst_root_loc, name, &obj_loc/*out*/, H5P_LINK_ACCESS_DEFAULT, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, H5_ITER_ERROR, "object not found")
+ obj_found = TRUE;
+
+ /* Check object and add to skip list if appropriate */
+ if(H5O_copy_search_comm_dt_check(&obj_oloc, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "can't check object")
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(obj_found && H5G_loc_free(&obj_loc) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_search_comm_dt
+ *
+ * Purpose: Checks if the committed datatype present in oh_src matches any
+ * in the destination file, building the destination file
+ * skiplist as necessary.
+ *
+ * Return: TRUE if a match is found in the destination file
+ * - oloc_dst will contain the address
+ * FALSE if a match is not found
+ * Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Sep 27 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src,
+ H5O_loc_t *oloc_dst/*in, out*/, hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *dst_addr; /* Destination datatype address */
+ H5G_loc_t dst_root_loc = {NULL, NULL}; /* Destination root group location */
+ H5O_copy_search_comm_dt_ud_t udata; /* Group iteration user data */
+ herr_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(oh_src);
+ HDassert(oloc_dst);
+ HDassert(oloc_dst->file);
+ HDassert(H5F_FILE_ID(oloc_dst->file) >= 0);
+ HDassert(cpy_info);
+
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the source datatype */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read_oh(file_src, dxpl_id, oh_src, H5O_DTYPE_ID, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Get destination object fileno */
+ H5F_GET_FILENO(oloc_dst->file, key->fileno);
+
+ /* Check if the destination dtype list exists, create it if it does not */
+ if(!cpy_info->dst_dt_list) {
+ /* Create the skip list */
+ if(NULL == (cpy_info->dst_dt_list = H5SL_create(H5SL_TYPE_GENERIC, H5O_copy_comm_dt_cmp)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create skip list for committed datatypes")
+
+ /* Add suggested types to list, if they are present */
+ if(cpy_info->dst_dt_suggestion_list) {
+ H5O_copy_dtype_merge_list_t *suggestion = cpy_info->dst_dt_suggestion_list;
+ H5G_loc_t obj_loc; /* Location of object */
+ H5O_loc_t obj_oloc; /* Object's object location */
+ H5G_name_t obj_path; /* Object's group hier. path */
+
+ /* Set up the root group in the destination file */
+ if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(oloc_dst->file))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group")
+ if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(oloc_dst->file))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group")
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Build udata */
+ udata.dst_dt_list = cpy_info->dst_dt_list;
+ udata.dst_root_loc = &dst_root_loc;
+ udata.obj_oloc.file = NULL;
+ udata.obj_oloc.addr = HADDR_UNDEF;
+ udata.dxpl_id = dxpl_id;
+
+ /* Walk through the list of datatype suggestions */
+ while(suggestion) {
+ /* Find the object */
+ if(H5G_loc_find(&dst_root_loc, suggestion->path, &obj_loc/*out*/, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0)
+ /* Ignore errors - i.e. suggestions not present in
+ * destination file */
+ H5E_clear_stack(NULL);
+ else
+ /* Check object and add to skip list if appropriate */
+ if(H5O_copy_search_comm_dt_check(&obj_oloc, &udata) < 0) {
+ if(H5G_loc_free(&obj_loc) < 0)
+ HERROR(H5E_OHDR, H5E_CANTRELEASE, "can't free location");
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't check object")
+ } /* end if */
+
+ /* Free location */
+ if(H5G_loc_free(&obj_loc) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't free location");
+
+ /* Advance the suggestion pointer */
+ suggestion = suggestion->next;
+ } /* end while */
+ } /* end if */
+ }
+
+ if(!cpy_info->dst_dt_list_complete) {
+ /* Search for the type in the destination file, and return its address
+ * if found, but only if the list is populated with and only with
+ * suggested types. We will search complete lists later. */
+ if(cpy_info->dst_dt_suggestion_list
+ && NULL != (dst_addr = (haddr_t *)H5SL_search(
+ cpy_info->dst_dt_list, key))) {
+ oloc_dst->addr = *dst_addr;
+ ret_value = TRUE;
+ } /* end if */
+ else {
+ H5O_mcdt_search_ret_t search_cb_ret = H5O_MCDT_SEARCH_CONT;
+
+ /* Make callback to see if we should search destination file */
+ if(cpy_info->mcdt_cb)
+ if((search_cb_ret = cpy_info->mcdt_cb(cpy_info->mcdt_ud)) == H5O_MCDT_SEARCH_ERROR)
+ HGOTO_ERROR(H5E_OHDR, H5E_CALLBACK, FAIL, "callback returned error")
+
+ if(search_cb_ret == H5O_MCDT_SEARCH_CONT) {
+ /* Build the complete dst dt list */
+ /* Set up the root group in the destination file, if necessary */
+ if(!dst_root_loc.oloc) {
+ HDassert(!dst_root_loc.path);
+ if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(oloc_dst->file))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group")
+ if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(oloc_dst->file))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group")
+ } /* end if */
+ else
+ HDassert(dst_root_loc.path);
+
+ /* Build udata. Note that this may be done twice in some cases, but
+ * it should be rare and should be cheaper on average than trying to
+ * keep track of whether it was done before. */
+ udata.dst_dt_list = cpy_info->dst_dt_list;
+ udata.dst_root_loc = &dst_root_loc;
+ udata.obj_oloc.file = NULL;
+ udata.obj_oloc.addr = HADDR_UNDEF;
+ udata.dxpl_id = dxpl_id;
+
+ /* Traverse the destination file, adding committed datatypes to the skip
+ * list */
+ if(H5G_visit(H5F_FILE_ID(oloc_dst->file), "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5O_copy_search_comm_dt_cb, &udata, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed")
+ cpy_info->dst_dt_list_complete = TRUE;
+ } /* end if */
+ else
+ if(search_cb_ret != H5O_MCDT_SEARCH_STOP)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown return value for callback")
+ } /* end if */
+ } /* end if */
+
+ /* Search for the type in the destination file, and return its address if
+ * found, but only if the list is complete */
+ if(cpy_info->dst_dt_list_complete) {
+ if(NULL != (dst_addr = (haddr_t *)H5SL_search(cpy_info->dst_dt_list, key))) {
+ oloc_dst->addr = *dst_addr;
+ ret_value = TRUE;
+ } /* end if */
+ } /* end if */
+
+done:
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_search_comm_dt */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_insert_comm_dt
+ *
+ * Purpose: Insert the committed datatype at oloc_dst into the merge committed
+ * dt skiplist. The datatype must not be present already.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Oct 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_insert_comm_dt(H5F_t *file_src, H5O_t *oh_src, H5O_loc_t *oloc_dst,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
+{
+ H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */
+ haddr_t *addr = NULL; /* Destination object address */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity checks */
+ HDassert(oh_src);
+ HDassert(oloc_dst);
+ HDassert(oloc_dst->file);
+ HDassert(oloc_dst->addr != HADDR_UNDEF);
+ HDassert(cpy_info);
+ HDassert(cpy_info->dst_dt_list);
+
+ /* Allocate key */
+ if(NULL == (key = H5FL_MALLOC(H5O_copy_search_comm_dt_key_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Read the datatype. Read from the source file because the destination
+ * object could be changed in the post-copy. */
+ if(NULL == (key->dt = (H5T_t *)H5O_msg_read_oh(file_src, dxpl_id, oh_src, H5O_DTYPE_ID, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't read DTYPE message")
+
+ /* Get destination object fileno */
+ H5F_GET_FILENO(oloc_dst->file, key->fileno);
+
+ /* Allocate destination address */
+ if(NULL == (addr = H5FL_MALLOC(haddr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add the destination datatype to the skip list */
+ *addr = oloc_dst->addr;
+ if(H5SL_insert(cpy_info->dst_dt_list, addr, key) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+
+done:
+ if(ret_value < 0) {
+ if(key) {
+ if(key->dt)
+ key->dt = (H5T_t *)H5O_msg_free(H5O_DTYPE_ID, key->dt);
+ key = H5FL_FREE(H5O_copy_search_comm_dt_key_t, key);
+ } /* end if */
+ if(addr)
+ addr = H5FL_FREE(haddr_t, addr);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_insert_comm_dt */
+
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 9ccb51b..1b602c7 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -43,6 +43,9 @@ static herr_t H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src,
static void *H5O_dtype_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+static herr_t H5O_dtype_shared_post_copy_upd(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
+ H5O_copy_t *cpy_info);
static herr_t H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -63,6 +66,7 @@ static herr_t H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#define H5O_SHARED_COPY_FILE_REAL H5O_dtype_copy_file
#define H5O_SHARED_POST_COPY_FILE H5O_dtype_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#define H5O_SHARED_POST_COPY_FILE_UPD H5O_dtype_shared_post_copy_upd
#define H5O_SHARED_DEBUG H5O_dtype_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_dtype_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
@@ -1575,6 +1579,40 @@ done:
} /* end H5O_dtype_copy_file() */
+/*-------------------------------------------------------------------------
+ * Function: H5O_dtype_shared_post_copy_upd
+ *
+ * Purpose: Update a message after the shared message operations
+ * during the post-copy loop
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * November 8, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_dtype_shared_post_copy_upd(const H5O_loc_t UNUSED *src_oloc,
+ const void UNUSED *mesg_src, H5O_loc_t UNUSED *dst_oloc, void *mesg_dst,
+ hid_t UNUSED dxpl_id, H5O_copy_t UNUSED *cpy_info)
+{
+ H5T_t *dt_dst = (H5T_t *)mesg_dst; /* Destination datatype */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(dt_dst->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
+ HDassert(H5T_committed(dt_dst));
+ dt_dst->oloc.file = dt_dst->sh_loc.file;
+ dt_dst->oloc.addr = dt_dst->sh_loc.u.loc.oh_addr;
+ } /* end if */
+ else
+ HDassert(!H5T_committed(dt_dst));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_dtype_shared_post_copy_upd */
+
+
/*--------------------------------------------------------------------------
NAME
H5O_dtype_debug
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index e4b21f0..3630cf4 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -36,8 +36,8 @@ static void *H5O_efl_copy(const void *_mesg, void *_dest);
static size_t H5O_efl_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
static herr_t H5O_efl_reset(void *_mesg);
static void *H5O_efl_copy_file(H5F_t *file_src, void *mesg_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info,
- void *udata, hid_t dxpl_id);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
static herr_t H5O_efl_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -455,8 +455,8 @@ done:
*/
static void *
H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info,
- void UNUSED *_udata, hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t UNUSED *cpy_info, void UNUSED *_udata, hid_t dxpl_id)
{
H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src;
H5O_efl_t *efl_dst = NULL;
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index 9fa6108..f5569dc 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -63,6 +63,7 @@ static herr_t H5O_fill_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *s
#undef H5O_SHARED_COPY_FILE_REAL
#define H5O_SHARED_POST_COPY_FILE H5O_fill_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_fill_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_fill_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
@@ -95,6 +96,7 @@ static herr_t H5O_fill_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *s
#undef H5O_SHARED_POST_COPY_FILE
#define H5O_SHARED_POST_COPY_FILE H5O_fill_new_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#undef H5O_SHARED_DEBUG
#define H5O_SHARED_DEBUG H5O_fill_new_shared_debug
#undef H5O_SHARED_DEBUG_REAL
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 1b17bff..e912d8c 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -46,8 +46,8 @@ static herr_t H5O_layout_free(void *_mesg);
static herr_t H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
void *_mesg);
static void *H5O_layout_copy_file(H5F_t *file_src, void *mesg_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info,
- void *udata, hid_t dxpl_id);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
static herr_t H5O_layout_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -587,8 +587,8 @@ done:
*/
static void *
H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void *_udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id)
{
H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
H5O_layout_t *layout_src = (H5O_layout_t *) mesg_src;
diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c
index acdd1e1..e96483a 100644
--- a/src/H5Olinfo.c
+++ b/src/H5Olinfo.c
@@ -46,10 +46,11 @@ static herr_t H5O_linfo_free(void *_mesg);
static herr_t H5O_linfo_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
void *_mesg);
static void *H5O_linfo_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info,
- void *udata, hid_t dxpl_id);
-static herr_t H5O_linfo_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+static herr_t H5O_linfo_post_copy_file(const H5O_loc_t *parent_src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_linfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -379,8 +380,8 @@ done:
*/
static void *
H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void *_udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id)
{
H5O_linfo_t *linfo_src = (H5O_linfo_t *) native_src;
H5O_linfo_t *linfo_dst = NULL;
@@ -501,7 +502,8 @@ done:
*/
static herr_t
H5O_linfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
- H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_linfo_t *linfo_src = (const H5O_linfo_t *)mesg_src;
H5O_linfo_t *linfo_dst = (H5O_linfo_t *)mesg_dst;
diff --git a/src/H5Olink.c b/src/H5Olink.c
index ccc6d0e..88c9e28 100644
--- a/src/H5Olink.c
+++ b/src/H5Olink.c
@@ -49,10 +49,11 @@ static herr_t H5O_link_free(void *_mesg);
static herr_t H5O_link_pre_copy_file(H5F_t *file_src, const void *mesg_src,
hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
static void *H5O_link_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata,
- hid_t dxpl_id);
-static herr_t H5O_link_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+static herr_t H5O_link_post_copy_file(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_link_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -710,8 +711,8 @@ H5O_link_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
*/
static void *
H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info, void UNUSED *udata,
- hid_t UNUSED dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t UNUSED *cpy_info, void UNUSED *udata, hid_t UNUSED dxpl_id)
{
H5O_link_t *link_src = (H5O_link_t *)native_src;
void *ret_value; /* Return value */
@@ -751,7 +752,8 @@ done:
*/
static herr_t
H5O_link_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
- H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_link_t *link_src = (const H5O_link_t *)mesg_src;
H5O_link_t *link_dst = (H5O_link_t *)mesg_dst;
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index f12c835..c9a0997 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -1855,7 +1855,7 @@ done:
void *
H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
- H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
+ unsigned *mesg_flags, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
{
void *ret_value;
@@ -1873,7 +1873,7 @@ H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
/* The copy_file callback will return an H5O_shared_t only if the message
* to be copied is a committed datatype.
*/
- if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, recompute_size, cpy_info, udata, dxpl_id)))
+ if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, recompute_size, mesg_flags, cpy_info, udata, dxpl_id)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object header message to file")
done:
@@ -1986,7 +1986,7 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header")
/* Update the message flags */
- idx_msg->flags = mesg_flags;
+ idx_msg->flags = (uint8_t)mesg_flags;
/* Mark the message as modified */
idx_msg->dirty = TRUE;
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index d4df79b..d4cc3fb 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -234,8 +234,8 @@ struct H5O_msg_class_t {
herr_t (*set_share)(void*, const H5O_shared_t*); /* Set shared information */
htri_t (*can_share)(const void *); /* Is message allowed to be shared? */
herr_t (*pre_copy_file)(H5F_t *, const void *, hbool_t *, const H5O_copy_t *, void *); /*"pre copy" action when copying native value to file */
- void *(*copy_file)(H5F_t *, void *, H5F_t *, hbool_t *, H5O_copy_t *, void *, hid_t); /*copy native value to file */
- herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, hid_t, H5O_copy_t *); /*"post copy" action when copying native value to file */
+ void *(*copy_file)(H5F_t *, void *, H5F_t *, hbool_t *, unsigned *, H5O_copy_t *, void *, hid_t); /*copy native value to file */
+ herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, unsigned *, hid_t, H5O_copy_t *); /*"post copy" action when copying native value to file */
herr_t (*get_crt_index)(const void *, H5O_msg_crt_idx_t *); /* Get message's creation index */
herr_t (*set_crt_index)(void *, H5O_msg_crt_idx_t); /* Set message's creation index */
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
@@ -550,7 +550,7 @@ H5_DLL herr_t H5O_msg_remove_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *ty
int sequence, H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
H5_DLL void *H5O_msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src,
void *mesg_src, H5F_t *file_dst, hbool_t *recompute_size,
- H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+ unsigned *mesg_flags, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
H5_DLL herr_t H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type,
const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id);
@@ -587,10 +587,12 @@ H5_DLL herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
const H5O_msg_class_t *mesg_type, H5O_shared_t *sh_mesg);
H5_DLL herr_t H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
const H5O_msg_class_t *mesg_type, const void *_native_src, void *_native_dst,
- hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
+ hbool_t *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
+ void *udata, hid_t dxpl_id);
H5_DLL herr_t H5O_shared_post_copy_file (H5F_t *f,
const H5O_msg_class_t *mesg_type, const H5O_shared_t *shared_src,
- H5O_shared_t *shared_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5O_shared_t *shared_dst, unsigned *mesg_flags, hid_t dxpl_id,
+ H5O_copy_t *cpy_info);
H5_DLL herr_t H5O_shared_debug(const H5O_shared_t *mesg, FILE *stream,
int indent, int fwidth);
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 89ce865..f626106 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -61,6 +61,7 @@ static herr_t H5O_pline_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#undef H5O_SHARED_COPY_FILE_REAL
#define H5O_SHARED_POST_COPY_FILE H5O_pline_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_pline_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_pline_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 97bd9a7..8e2dfa4 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -99,7 +99,9 @@ typedef struct H5O_t H5O_t;
#endif /* H5O_ENABLE_BAD_MESG_COUNT */
/* ========= Object Copy properties ============ */
-#define H5O_CPY_OPTION_NAME "copy object" /* Copy options */
+#define H5O_CPY_OPTION_NAME "copy object" /* Copy options */
+#define H5O_CPY_MERGE_COMM_DT_LIST_NAME "merge committed dtype list" /* List of datatype paths to search in the dest file for merging */
+#define H5O_CPY_MCDT_SEARCH_CB_NAME "committed dtype list search" /* Callback function when the search for a matching committed datatype is complete */
/* If the module using this macro is allowed access to the private variables, access them directly */
#ifdef H5O_PACKAGE
@@ -133,6 +135,18 @@ typedef struct H5O_loc_t {
* its file's count of open objects. */
} H5O_loc_t;
+/* Typedef for linked list of datatype merge suggestions */
+typedef struct H5O_copy_dtype_merge_list_t {
+ char *path; /* Path to datatype in destination file */
+ struct H5O_copy_dtype_merge_list_t *next; /* Next object in list */
+} H5O_copy_dtype_merge_list_t;
+
+/* Structure for callback property before searching the global list of committed datatypes at destination */
+typedef struct H5O_mcdt_cb_info_t {
+ H5O_mcdt_search_cb_t func;
+ void *user_data;
+} H5O_mcdt_cb_info_t;
+
/* Settings/flags for copying an object */
typedef struct H5O_copy_t {
hbool_t copy_shallow; /* Flag to perform shallow hierarchy copy */
@@ -141,10 +155,16 @@ typedef struct H5O_copy_t {
hbool_t expand_ref; /* Flag to expand object references */
hbool_t copy_without_attr; /* Flag to not copy attributes */
hbool_t preserve_null; /* Flag to not delete NULL messages */
+ hbool_t merge_comm_dt; /* Flag to merge committed datatypes in dest file */
+ H5O_copy_dtype_merge_list_t *dst_dt_suggestion_list; /* Suggestions for merging committed datatypes */
int curr_depth; /* Current depth in hierarchy copied */
int max_depth; /* Maximum depth in hierarchy to copy */
H5SL_t *map_list; /* Skip list to hold address mappings */
+ H5SL_t *dst_dt_list; /* Skip list to hold committed datatypes in dest file */
+ hbool_t dst_dt_list_complete; /* Whether the destination datatype list is complete (i.e. not only populated with "suggestions" from H5Padd_merge_committed_dtype_path) */
H5O_t *oh_dst; /* The destination object header */
+ H5O_mcdt_search_cb_t mcdt_cb; /* The callback to invoke before searching the global list of committed datatypes at destination */
+ void *mcdt_ud; /* User data passed to callback */
} H5O_copy_t;
/* Header message IDs */
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index 2379d6b..a7d386a 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -43,7 +43,8 @@
#define H5O_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /* Copy objects that are pointed by references */
#define H5O_COPY_WITHOUT_ATTR_FLAG (0x0010u) /* Copy object without copying attributes */
#define H5O_COPY_PRESERVE_NULL_FLAG (0x0020u) /* Copy NULL messages (empty space) */
-#define H5O_COPY_ALL (0x003Fu) /* All object copying flags (for internal checking) */
+#define H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG (0x0040u) /* Merge committed datatypes in dest file */
+#define H5O_COPY_ALL (0x007Fu) /* All object copying flags (for internal checking) */
/* Flags for shared message indexes.
* Pass these flags in using the mesg_type_flags parameter in
@@ -131,6 +132,14 @@ typedef uint32_t H5O_msg_crt_idx_t;
typedef herr_t (*H5O_iterate_t)(hid_t obj, const char *name, const H5O_info_t *info,
void *op_data);
+typedef enum H5O_mcdt_search_ret_t {
+ H5O_MCDT_SEARCH_ERROR = -1, /* Abort H5Ocopy */
+ H5O_MCDT_SEARCH_CONT, /* Continue the global search of all committed datatypes in the destination file */
+ H5O_MCDT_SEARCH_STOP /* Stop the search, but continue copying. The committed datatype will be copied but not merged. */
+} H5O_mcdt_search_ret_t;
+
+/* Callback to invoke when completing the search for a matching committed datatype from the committed dtype list */
+typedef H5O_mcdt_search_ret_t (*H5O_mcdt_search_cb_t)(void *op_data);
/********************/
/* Public Variables */
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index 8ae73f7..905c4e9 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -55,6 +55,7 @@ static herr_t H5O_sdspace_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
#undef H5O_SHARED_COPY_FILE_REAL
#define H5O_SHARED_POST_COPY_FILE H5O_sdspace_shared_post_copy_file
#undef H5O_SHARED_POST_COPY_FILE_REAL
+#undef H5O_SHARED_POST_COPY_FILE_UPD
#define H5O_SHARED_DEBUG H5O_sdspace_shared_debug
#define H5O_SHARED_DEBUG_REAL H5O_sdspace_debug
#include "H5Oshared.h" /* Shared Object Header Message Callbacks */
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 4cc30e8..c29e2c7 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -589,8 +589,8 @@ done:
herr_t
H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
const H5O_msg_class_t *mesg_type, const void *_native_src, void *_native_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
+ void UNUSED *udata, hid_t dxpl_id)
{
const H5O_shared_t *shared_src = (const H5O_shared_t *)_native_src; /* Alias to shared info in native source */
H5O_shared_t *shared_dst = (H5O_shared_t *)_native_dst; /* Alias to shared info in native destination message */
@@ -621,16 +621,18 @@ H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
/* Set copied metadata tag */
H5_BEGIN_TAG(dxpl_id, H5AC__COPIED_TAG, FAIL);
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5SM_DEFER, mesg_type->id, _native_dst, NULL) < 0)
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, H5SM_DEFER, mesg_type->id, _native_dst, mesg_flags) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to determine if message should be shared")
/* Reset metadata tag */
H5_END_TAG(FAIL);
} /* end if */
- else
+ else {
/* Mark the message as committed - as it will be committed in post copy
*/
H5O_UPDATE_SHARED(shared_dst, H5O_SHARE_TYPE_COMMITTED, file_dst, mesg_type->id, 0, HADDR_UNDEF)
+ *mesg_flags |= H5O_MSG_FLAG_SHARED;
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -657,8 +659,8 @@ done:
*/
herr_t
H5O_shared_post_copy_file(H5F_t *f, const H5O_msg_class_t *mesg_type,
- const H5O_shared_t *shared_src, H5O_shared_t *shared_dst, hid_t dxpl_id,
- H5O_copy_t *cpy_info)
+ const H5O_shared_t *shared_src, H5O_shared_t *shared_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -675,6 +677,7 @@ H5O_shared_post_copy_file(H5F_t *f, const H5O_msg_class_t *mesg_type,
H5O_loc_t src_oloc;
/* Copy the shared object from source to destination */
+ H5O_loc_reset(&dst_oloc);
dst_oloc.file = f;
src_oloc.file = shared_src->file;
src_oloc.addr = shared_src->u.loc.oh_addr;
@@ -688,7 +691,7 @@ H5O_shared_post_copy_file(H5F_t *f, const H5O_msg_class_t *mesg_type,
else
/* Share the message */
if(H5SM_try_share(f, dxpl_id, NULL, H5SM_WAS_DEFERRED, mesg_type->id,
- shared_dst, NULL) < 0)
+ shared_dst, mesg_flags) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't share message")
done:
diff --git a/src/H5Oshared.h b/src/H5Oshared.h
index ddacc25..3ec5709 100644
--- a/src/H5Oshared.h
+++ b/src/H5Oshared.h
@@ -320,7 +320,8 @@ done:
*/
static H5_inline void *
H5O_SHARED_COPY_FILE(H5F_t *file_src, void *_native_src, H5F_t *file_dst,
- hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
+ hbool_t *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
+ void *udata, hid_t dxpl_id)
{
void *dst_mesg = NULL; /* Destination message */
void *ret_value; /* Return value */
@@ -348,8 +349,8 @@ H5O_SHARED_COPY_FILE(H5F_t *file_src, void *_native_src, H5F_t *file_dst,
HDmemset(dst_mesg, 0, sizeof(H5O_shared_t));
/* Handle sharing destination message */
- if(H5O_shared_copy_file(file_src, file_dst, H5O_SHARED_TYPE,
- _native_src, dst_mesg, recompute_size, cpy_info, udata, dxpl_id) < 0)
+ if(H5O_shared_copy_file(file_src, file_dst, H5O_SHARED_TYPE, _native_src,
+ dst_mesg, recompute_size, mesg_flags, cpy_info, udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "unable to determine if message should be shared")
/* Set return value */
@@ -383,7 +384,8 @@ done:
*/
static H5_inline herr_t
H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
- H5O_loc_t *oloc_dst, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+ H5O_loc_t *oloc_dst, void *mesg_dst, unsigned *mesg_flags, hid_t dxpl_id,
+ H5O_copy_t *cpy_info)
{
const H5O_shared_t *shared_src = (const H5O_shared_t *)mesg_src; /* Alias to shared info in native source */
H5O_shared_t *shared_dst = (H5O_shared_t *)mesg_dst; /* Alias to shared info in native destination */
@@ -405,7 +407,7 @@ H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
#endif /* H5O_SHARED_POST_COPY_FILE */
#ifdef H5O_SHARED_POST_COPY_FILE_REAL
- /* Call native message's copy file callback to copy the message */
+ /* Call native message's post copy file callback to copy the message */
if(H5O_SHARED_POST_COPY_FILE_REAL(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) <0 )
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy native message to another file")
#endif /* H5O_SHARED_POST_COPY_FILE_REAL */
@@ -414,9 +416,16 @@ H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
* production if the DEFER pass determined it will not be shared; debug mode
* verifies that it is indeed the case */
if(H5O_shared_post_copy_file(oloc_dst->file, H5O_SHARED_TYPE,
- shared_src, shared_dst, dxpl_id, cpy_info) < 0)
+ shared_src, shared_dst, mesg_flags, dxpl_id, cpy_info) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to fix shared message in post copy")
+#ifdef H5O_SHARED_POST_COPY_FILE_UPD
+ /* Call native message's post copy file update callback to update the
+ * message */
+ if(H5O_SHARED_POST_COPY_FILE_UPD(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to update native message")
+#endif /* H5O_SHARED_POST_COPY_FILE_UPD */
+
/* Make sure that if the the source or destination is committed, both are
* committed */
HDassert((shared_src->type == H5O_SHARE_TYPE_COMMITTED)
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 42cd92c..d5f5f86 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -44,10 +44,11 @@ static size_t H5O_stab_size(const H5F_t *f, hbool_t disable_shared, const void *
static herr_t H5O_stab_free(void *_mesg);
static herr_t H5O_stab_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg);
static void *H5O_stab_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, void *_udata,
- hid_t dxpl_id);
-static herr_t H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
+ H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
+ H5O_copy_t *cpy_info, void *_udata, hid_t dxpl_id);
+static herr_t H5O_stab_post_copy_file(const H5O_loc_t *src_oloc,
+ const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ unsigned *mesg_flags, hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_stab_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -307,8 +308,8 @@ done:
*/
static void *
H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst,
- hbool_t UNUSED *recompute_size, H5O_copy_t UNUSED *cpy_info, void *_udata,
- hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, unsigned UNUSED *mesg_flags,
+ H5O_copy_t UNUSED *cpy_info, void *_udata, hid_t dxpl_id)
{
H5O_stab_t *stab_src = (H5O_stab_t *) native_src;
H5O_stab_t *stab_dst = NULL;
@@ -370,8 +371,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
+H5O_stab_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
+ H5O_loc_t *dst_oloc, void *mesg_dst, unsigned UNUSED *mesg_flags,
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
const H5O_stab_t *stab_src = (const H5O_stab_t *)mesg_src;
H5O_stab_t *stab_dst = (H5O_stab_t *)mesg_dst;
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index 6a3067d..32793e6 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -392,7 +392,7 @@ H5P_dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t UNUSED si
/* Sanity check */
HDassert(layout1);
- HDassert(layout1);
+ HDassert(layout2);
HDassert(size == sizeof(H5O_layout_t));
/* Check for different layout type */
diff --git a/src/H5Pocpypl.c b/src/H5Pocpypl.c
index af50d80..e61a0d7 100644
--- a/src/H5Pocpypl.c
+++ b/src/H5Pocpypl.c
@@ -35,7 +35,9 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Ppkg.h" /* Property lists */
@@ -47,7 +49,13 @@
/* Definitions for copy options */
#define H5O_CPY_OPTION_SIZE sizeof(unsigned)
#define H5O_CPY_OPTION_DEF 0
-
+/* Definitions for merge committed dtype list */
+#define H5O_CPY_MERGE_COMM_DT_LIST_SIZE sizeof(char *)
+#define H5O_CPY_MERGE_COMM_DT_LIST_DEF NULL
+#define H5O_CPY_MERGE_COMM_DT_LIST_CMP H5P_ocpy_merge_comm_dt_list_cmp
+/* Definitions for callback function when completing the search for a matching committed datatype from the committed dtype list */
+#define H5O_CPY_MCDT_SEARCH_CB_SIZE sizeof(H5O_mcdt_cb_info_t)
+#define H5O_CPY_MCDT_SEARCH_CB_DEF {NULL,NULL}
/******************/
/* Local Typedefs */
@@ -63,8 +71,17 @@
/* Local Prototypes */
/********************/
+/* General routines */
+static H5O_copy_dtype_merge_list_t *H5P_free_merge_comm_dtype_list(H5O_copy_dtype_merge_list_t *dt_list);
+
/* Property class callbacks */
static herr_t H5P_ocpy_reg_prop(H5P_genclass_t *pclass);
+static herr_t H5P_ocpy_copy(hid_t dst_plist_id, hid_t src_plist_id,
+ void *copy_data);
+static herr_t H5P_ocpy_close(hid_t ocpypl_id, void *close_data);
+
+/* Property callbacks */
+static int H5P_ocpy_merge_comm_dt_list_cmp(const void *value1, const void *value2, size_t size);
/*********************/
@@ -80,9 +97,9 @@ const H5P_libclass_t H5P_CLS_OCPY[1] = {{
H5P_ocpy_reg_prop, /* Default property registration routine */
NULL, /* Class creation callback */
NULL, /* Class creation callback info */
- NULL, /* Class copy callback */
+ H5P_ocpy_copy, /* Class copy callback */
NULL, /* Class copy callback info */
- NULL, /* Class close callback */
+ H5P_ocpy_close, /* Class close callback */
NULL /* Class close callback info */
}};
@@ -96,6 +113,9 @@ const H5P_libclass_t H5P_CLS_OCPY[1] = {{
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5O_copy_dtype_merge_list_t struct */
+H5FL_DEFINE(H5O_copy_dtype_merge_list_t);
+
/*-------------------------------------------------------------------------
@@ -109,10 +129,12 @@ const H5P_libclass_t H5P_CLS_OCPY[1] = {{
* October 31, 2006
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5P_ocpy_reg_prop(H5P_genclass_t *pclass)
{
unsigned ocpy_option = H5O_CPY_OPTION_DEF; /* Default object copy flags */
+ H5O_copy_dtype_merge_list_t *merge_comm_dtype_list = H5O_CPY_MERGE_COMM_DT_LIST_DEF; /* Default merge committed dtype list */
+ H5O_mcdt_cb_info_t mcdt_cb = H5O_CPY_MCDT_SEARCH_CB_DEF; /* Default callback before searching the global list of committed datatypes at destination */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -121,12 +143,222 @@ H5P_ocpy_reg_prop(H5P_genclass_t *pclass)
if(H5P_register_real(pclass, H5O_CPY_OPTION_NAME, H5O_CPY_OPTION_SIZE, &ocpy_option, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register merge named dtype list property */
+ if(H5P_register_real(pclass, H5O_CPY_MERGE_COMM_DT_LIST_NAME, H5O_CPY_MERGE_COMM_DT_LIST_SIZE, &merge_comm_dtype_list, NULL, NULL, NULL, NULL, NULL, H5O_CPY_MERGE_COMM_DT_LIST_CMP, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register property for callback when completing the search for a matching named datatype from the named dtype list */
+ if(H5P_register_real(pclass, H5O_CPY_MCDT_SEARCH_CB_NAME, H5O_CPY_MCDT_SEARCH_CB_SIZE, &mcdt_cb, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_ocpy_reg_prop() */
/*-------------------------------------------------------------------------
+ * Function: H5P_ocpy_copy
+ *
+ * Purpose: Callback routine which is called whenever any object
+ * copy property list is copied. This routine copies
+ * the properties from the old list to the new list.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 28, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_ocpy_copy(hid_t dst_plist_id, hid_t src_plist_id, void UNUSED *copy_data)
+{
+ H5O_copy_dtype_merge_list_t *src_dt_list, *dst_dt_list = NULL; /* Source & destination merge named datatype lists */
+ H5O_copy_dtype_merge_list_t *dst_dt_list_tail = NULL, *tmp_dt_list = NULL; /* temporary merge named datatype lists */
+ H5P_genplist_t *src_plist; /* Pointer to source property list */
+ H5P_genplist_t *dst_plist; /* Pointer to destination property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Verify property list IDs */
+ if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object copy property list")
+ if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object copy property list")
+
+ /* Get the merge committed dtype list property from the old property list */
+ if(H5P_get(src_plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &src_dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge named dtype list")
+
+ /* Make copy of merge committed dtype list */
+ while(src_dt_list) {
+ /* Copy src_dt_list */
+ if(NULL == (tmp_dt_list = H5FL_CALLOC(H5O_copy_dtype_merge_list_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (tmp_dt_list->path = H5MM_strdup(src_dt_list->path)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Add copied node to dest dtype list */
+ if(dst_dt_list_tail) {
+ dst_dt_list_tail->next = tmp_dt_list;
+ dst_dt_list_tail = tmp_dt_list;
+ } /* end if */
+ else {
+ dst_dt_list = tmp_dt_list;
+ dst_dt_list_tail = tmp_dt_list;
+ } /* end else */
+ tmp_dt_list = NULL;
+
+ /* Advance src_dt_list pointer */
+ src_dt_list = src_dt_list->next;
+ } /* end while */
+
+ /* Set the merge named dtype list property for the destination property list
+ */
+ if(H5P_set(dst_plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dst_dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge committed dtype list")
+
+done:
+ if(ret_value < 0) {
+ dst_dt_list = H5P_free_merge_comm_dtype_list(dst_dt_list);
+ if(tmp_dt_list) {
+ tmp_dt_list->path = (char *)H5MM_xfree(tmp_dt_list->path);
+ tmp_dt_list = H5FL_FREE(H5O_copy_dtype_merge_list_t, tmp_dt_list);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocpy_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_ocpy_close
+ *
+ * Purpose: Callback routine which is called whenever any object copy
+ * property list is closed. This routine performs any generic
+ * cleanup needed on the properties the library put into the
+ * list.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 28, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static herr_t
+H5P_ocpy_close(hid_t ocpypl_id, void UNUSED *close_data)
+{
+ H5O_copy_dtype_merge_list_t *dt_list; /* Merge named datatype list */
+ H5P_genplist_t *plist; /* Property list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check arguments */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(ocpypl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object copy property list")
+
+ /* Get the merge named dtype list property from the old property list */
+ if(H5P_get(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge named dtype list")
+
+ /* Free the merge named dtype list */
+ dt_list = H5P_free_merge_comm_dtype_list(dt_list);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocpy_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_ocpy_merge_comm_dt_list_cmp
+ *
+ * Purpose: Callback routine which is called whenever the merge
+ * named dtype property in the object copy property list
+ * is compared.
+ *
+ * Return: positive if VALUE1 is greater than VALUE2, negative if
+ * VALUE2 is greater than VALUE1 and zero if VALUE1 and
+ * VALUE2 are equal.
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 28, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5P_ocpy_merge_comm_dt_list_cmp(const void *_dt_list1, const void *_dt_list2,
+ size_t UNUSED size)
+{
+ const H5O_copy_dtype_merge_list_t *dt_list1 = *(H5O_copy_dtype_merge_list_t * const *)_dt_list1, /* Create local aliases for values */
+ *dt_list2 = *(H5O_copy_dtype_merge_list_t * const *)_dt_list2;
+ herr_t ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity check */
+ HDassert(_dt_list1);
+ HDassert(_dt_list2);
+ HDassert(size == sizeof(H5O_copy_dtype_merge_list_t *));
+
+ /* Walk through the lists, comparing each path. For the lists to be the
+ * same, the paths must be in the same order. */
+ while(dt_list1 && dt_list2) {
+ /* Compare paths */
+ ret_value = HDstrcmp(dt_list1->path, dt_list2->path);
+ if(ret_value != 0) HGOTO_DONE(ret_value)
+
+ /* Advance to next node */
+ dt_list1 = dt_list1->next;
+ dt_list2 = dt_list2->next;
+ } /* end while */
+
+ /* Check if one list is longer than the other */
+ if(dt_list1) HGOTO_DONE(1)
+ if(dt_list2) HGOTO_DONE(-1)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_ocpy_merge_comm_dt_list_cmp() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_free_merge_comm_dtype_list
+ *
+ * Purpose: Frees the provided merge named dtype list
+ *
+ * Return: NULL
+ *
+ * Programmer: Neil Fortner
+ * October 27, 2011
+ *-------------------------------------------------------------------------
+ */
+static H5O_copy_dtype_merge_list_t *
+H5P_free_merge_comm_dtype_list(H5O_copy_dtype_merge_list_t *dt_list)
+{
+ H5O_copy_dtype_merge_list_t *tmp_node;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Free the list */
+ while(dt_list) {
+ tmp_node = dt_list->next;
+ (void)H5MM_xfree(dt_list->path);
+ (void)H5FL_FREE(H5O_copy_dtype_merge_list_t, dt_list);
+ dt_list = tmp_node;
+ } /* end while */
+
+ FUNC_LEAVE_NOAPI(NULL);
+} /* H5P_free_merge_comm_dtype_list */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_copy_object
*
* Purpose: Set properties when copying an object (group, dataset, and datatype)
@@ -207,3 +439,206 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_copy_object() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Padd_merge_committed_dtype_path
+ *
+ * Purpose: Adds path to the list of paths to search first in the
+ * target file when merging committed datatypes during H5Ocopy
+ * (i.e. when using the H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG flag
+ * as set by H5Pset_copy_object). If the source named
+ * dataype is not found in the list of paths created by this
+ * function, the entire file will be searched.
+ *
+ * Usage: H5Padd_merge_committed_dtype_path(plist_id, path)
+ * hid_t plist_id; IN: Property list to copy object
+ * const char *path; IN: Path to add to list
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * October 27, 2011
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Padd_merge_committed_dtype_path(hid_t plist_id, const char *path)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_copy_dtype_merge_list_t *old_list; /* Merge committed dtype list currently present */
+ H5O_copy_dtype_merge_list_t *new_obj = NULL; /* New object to add to list */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check parameters */
+ if(!path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no path specified")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get dtype list */
+ if(H5P_get(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &old_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge named dtype list")
+
+ /* Add the new path to the list */
+ if(NULL == (new_obj = H5FL_CALLOC(H5O_copy_dtype_merge_list_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (new_obj->path = H5MM_strdup(path)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ new_obj->next = old_list;
+
+ /* Update the list stored in the property list */
+ if(H5P_set(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &new_obj) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge named dtype list")
+
+done:
+ if(ret_value < 0)
+ if(new_obj) {
+ new_obj->path = (char *)H5MM_xfree(new_obj->path);
+ new_obj = H5FL_FREE(H5O_copy_dtype_merge_list_t, new_obj);
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Padd_merge_committed_dtype_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pfree_merge_committed_dtype_paths
+ *
+ * Purpose: Frees and clears the list of paths created by
+ * H5Padd_merge_committed_dtype_path. A new list may then be
+ * created by calling H5Padd_merge_committed_dtype_path again.
+ *
+ * Usage: H5Pfree_merge_committed_dtype_paths(plist_id)
+ * hid_t plist_id; IN: Property list to copy object
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * October 27, 2011
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pfree_merge_committed_dtype_paths(hid_t plist_id)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_copy_dtype_merge_list_t *dt_list; /* Merge committed dtype list currently present */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get dtype list */
+ if(H5P_get(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get merge committed dtype list")
+
+ /* Free dtype list */
+ dt_list = H5P_free_merge_comm_dtype_list(dt_list);
+
+ /* Update the list stored in the property list (to NULL) */
+ if(H5P_set(plist, H5O_CPY_MERGE_COMM_DT_LIST_NAME, &dt_list) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set merge committed dtype list")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pfree_merge_committed_dtype_paths() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_mcdt_search_cb
+ *
+ * Purpose: Set the callback function when a matching committed datatype is not found
+ * from the list of paths stored in the object copy property list.
+ * H5Ocopy will invoke this callback before searching all committed datatypes
+ * at destination.
+ *
+ * Usage: H5Pset_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t func, void *op_data)
+ * hid_t plist_id; IN: Property list to copy object
+ * H5O_mcdt_search_cb_t func; IN: The callback function
+ * void *op_data; IN: The user data
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; November 28, 2011
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check if the callback function is NULL and the user data is non-NULL.
+ * This is almost certainly an error as the user data will not be used. */
+ if(!func && op_data)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Populate the callback info struct */
+ cb_info.func = func;
+ cb_info.user_data = op_data;
+
+ /* Set callback info */
+ if(H5P_set(plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set callback info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_mcdt_search_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_mcdt_search_cb
+ *
+ * Purpose: Retrieves the callback function and user data from the specified
+ * object copy property list.
+ *
+ * Usage: H5Pget_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t *func, void **op_data)
+ * hid_t plist_id; IN: Property list to copy object
+ * H5O_mcdt_search_cb_t *func; OUT: The callback function
+ * void **op_data; OUT: The user data
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; November 29, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, void **op_data)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_mcdt_cb_info_t cb_info; /* Callback info struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_COPY)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get callback info */
+ if(H5P_get(plist, H5O_CPY_MCDT_SEARCH_CB_NAME, &cb_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info")
+
+ if(func)
+ *func = cb_info.func;
+
+ if(op_data)
+ *op_data = cb_info.user_data;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_mcdt_search_cb() */
+
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index d4441a3..9015940 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -30,6 +30,7 @@
#include "H5FDpublic.h"
#include "H5Ipublic.h"
#include "H5Lpublic.h"
+#include "H5Opublic.h"
#include "H5MMpublic.h"
#include "H5Tpublic.h"
#include "H5Zpublic.h"
@@ -427,6 +428,10 @@ H5_DLL herr_t H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **
/* Object copy property list (OCPYPL) routines */
H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd);
H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/);
+H5_DLL herr_t H5Padd_merge_committed_dtype_path(hid_t plist_id, const char *path);
+H5_DLL herr_t H5Pfree_merge_committed_dtype_paths(hid_t plist_id);
+H5_DLL herr_t H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data);
+H5_DLL herr_t H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, void **op_data);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
diff --git a/src/H5SM.c b/src/H5SM.c
index 8c00d34..62efb50 100644
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -1099,7 +1099,7 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned defer_flags,
/* Set flags if this message was "written" without error and wasn't a
* 'defer' attempt; it is now either fully shared or "shareable".
*/
- if(mesg_flags && !(defer_flags & H5SM_DEFER)) {
+ if(mesg_flags) {
if(((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_HERE)
*mesg_flags |= H5O_MSG_FLAG_SHAREABLE;
else {
@@ -1109,7 +1109,8 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned defer_flags,
} /* end if */
done:
- HDassert(!ret_value || ((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_HERE
+ HDassert((ret_value != TRUE)
+ || ((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_HERE
|| ((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_SOHM);
#ifndef NDEBUG
/* If we previously deferred this operation, make sure the saved message
diff --git a/test/objcopy.c b/test/objcopy.c
index 9188713..6e33bce 100644
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -47,6 +47,7 @@ const char *FILENAME[] = {
"objcopy_src",
"objcopy_dst",
"objcopy_ext",
+ "objcopy_src2",
NULL
};
@@ -73,6 +74,7 @@ const char *FILENAME[] = {
#define NAME_DATATYPE_VL_VL "vlen of vlen of int"
#define NAME_DATASET_SIMPLE "dataset_simple"
#define NAME_DATASET_SIMPLE2 "dataset_simple_copy"
+#define NAME_DATASET_SIMPLE3 "dataset_simple_another_copy"
#define NAME_DATASET_COMPOUND "dataset_compound"
#define NAME_DATASET_CHUNKED "dataset_chunked"
#define NAME_DATASET_CHUNKED2 "dataset_chunked2"
@@ -89,6 +91,9 @@ const char *FILENAME[] = {
#define NAME_GROUP_UNCOPIED "/uncopied"
#define NAME_GROUP_EMPTY "/empty"
#define NAME_GROUP_TOP "/g0"
+#define NAME_GROUP_TOP2 "/g1"
+#define NAME_GROUP_TOP3 "/g2"
+#define NAME_GROUP_TOP4 "/g3"
#define NAME_GROUP_SUB "/g0/g00"
#define NAME_GROUP_SUB_2 "/g0/g01"
#define NAME_GROUP_SUB_SUB "/g0/g00/g000"
@@ -8097,6 +8102,3190 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_datatype_merge
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, October 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_datatype_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src1 = -1, fid_src2 = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src1_filename[NAME_BUF_SIZE];
+ char src2_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen) {
+ TESTING("H5Ocopy(): merging committed datatypes with reopen")
+ } /* end if */
+ else
+ TESTING("H5Ocopy(): merging committed datatypes")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src1_filename, sizeof src1_filename);
+ h5_fixname(FILENAME[3], src_fapl, src2_filename, sizeof src2_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source files */
+ if((fid_src1 = H5Fcreate(src1_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+ if((fid_src2 = H5Fcreate(src2_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file 1
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src1, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src1, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file 1 */
+ if(H5Fclose(fid_src1) < 0) TEST_ERROR
+
+ /*
+ * Populate source file 2
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src2, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src2, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file 1 */
+ if(H5Fclose(fid_src2) < 0) TEST_ERROR
+
+
+ /* open the source files with read-only */
+ if((fid_src1 = H5Fopen(src1_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+ if((fid_src2 = H5Fopen(src2_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge named dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy each entire file to the destination file (each with their own
+ * group), and verify the committed datatypes are merged
+ */
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* copy SRC1 to DST */
+ if(H5Ocopy(fid_src1, "/", fid_dst, NAME_GROUP_TOP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC2 to DST */
+ if(H5Ocopy(fid_src2, "/", fid_dst, NAME_GROUP_TOP2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open SRC1 committed dtype, get address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open SRC1 dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open SRC2 committed dtype, check address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open SRC2 dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Now copy only the datasets to the destination file, and verify the committed
+ * datatypes are merged
+ */
+ /* recreate destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* copy SRC1 to DST */
+ if(H5Ocopy(fid_src1, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC2 to DST */
+ if(H5Ocopy(fid_src2, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open SRC1 dset dtype, get address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open SRC2 dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC files */
+ if(H5Fclose(fid_src1) < 0) TEST_ERROR
+ if(H5Fclose(fid_src2) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src1);
+ H5Fclose(fid_src2);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_datatype_merge */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_datatype_merge_same_file
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy,
+ * while copying to the same file.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, October 11, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_datatype_merge_same_file(hid_t fcpl, hid_t fapl, hbool_t reopen)
+{
+ hid_t fid = -1; /* File ID */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t gid = -1; /* Group ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes to the source file with reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes to the source file")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filename */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create file */
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate first group
+ */
+ /* Create group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset */
+ if((did = H5Dcreate2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /*
+ * Populate second group
+ */
+ /* Create group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset */
+ if((did = H5Dcreate2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy each group to the destination group 3 (each with their own
+ * group), and verify the committed datatypes are merged as expected. All
+ * datatypes copied should reference (share an address with) the
+ * corresponding source datatype.
+ */
+ /* Create destination group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* copy group 1 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP, fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy group 2 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP2, fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open group 1 source committed dtype, get address */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 1 source dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 1 committed dtype, check address */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 1 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 source committed dtype, get address and make sure it is
+ * different from group 1 source committed dtype */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 2 source dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 committed dtype, check address */
+ if((tid = H5Topen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2 "/" NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open group 2 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP3 "/" NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Now copy only the datasets to the destination group, and verify the committed
+ * datatypes are merged as expected
+ */
+ /* Create destination group */
+ if((gid = H5Gcreate2(fid, NAME_GROUP_TOP4, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* copy SRC1 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC2 to DST */
+ if(H5Ocopy(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open group 1 source dset dtype, get address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 1 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 source dset dtype, get address and make sure it is
+ * different from group 1 source dset dtype */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP2 "/" NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open group 2 dset dtype, check address */
+ if((did = H5Dopen2(fid, NAME_GROUP_TOP4 "/" NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_datatype_merge_same_file */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_dt_merge_sugg
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy, and
+ * uses the suggestion list feature
+ * (H5Padd_merge_committed_dtype_path).
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Thursday, November 3, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_dt_merge_sugg(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "a" */
+ if((H5Tcommit2(fid_dst, "/a", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "b" */
+ if((H5Tcommit2(fid_dst, "/b", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy dataset using "/b" as a suggestion, and verify that it uses
+ * datatype "b" in the destination file
+ */
+ /* Add datatype suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/b") < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Now free suggestions, copy dataset without any suggestions, and verify
+ * that it uses datatype "a" in the destination file
+ */
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Delete destination dataset */
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset 2 dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_dt_merge_sugg */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_committed_dt_merge_attr
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy, with
+ * an attribute using an anonymous committed type in the
+ * destination.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Thursday, November 3, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_committed_dt_merge_attr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t gid = -1; /* Group ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes with attributes and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes with attributes")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* Create group */
+ if((gid = H5Gcreate2(fid_dst, NAME_GROUP_TOP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* create anonymous committed data type */
+ if((H5Tcommit_anon(fid_dst, tid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create attribute at SRC file */
+ if((aid = H5Acreate2(gid, "attr", tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Awrite(aid, tid, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * Copy dataset and verify that it uses the same committed datatype as the
+ * already existing attribute in the destination file.
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open attribute dtype, get address */
+ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_TOP, "attr", H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Aclose(aid);
+ H5Gclose(gid);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_committed_dt_merge_attr */
+
+/*
+ * Defines used for the committed datatype tests
+ */
+#define SRC_ROOT_GROUP "src_root"
+#define ROOT_NDT_INT "root_ndt_int"
+#define GROUP_NDT_SHORT "group_ndt_short"
+
+#define SRC_GRP "src_grp"
+#define DST_GRP "dst_grp"
+#define DST_GRP2 "dst_grp2"
+
+#define SRC_NDT_SHORT "src_ndt_short"
+#define SRC_NDT_INT "src_ndt_int"
+#define SRC_NDT_INT2 "src_ndt_int2"
+#define SRC_NDT_FLOAT "src_ndt_float"
+#define SRC_NDT_DOUBLE "src_ndt_double"
+
+#define DST_NDT_SHORT "dst_ndt_short"
+#define DST_NDT_INT "dst_ndt_int"
+#define DST_NDT_FLOAT "dst_ndt_float"
+#define DST_NDT_DOUBLE "dst_ndt_double"
+
+#define SRC_NDT_DSET "src_ndt_dset"
+#define SRC_NDT_DSET2 "src_ndt_dset2"
+#define SRC_NDT_DSET3 "src_ndt_dset3"
+
+#define SRC_DSET "src_dset"
+#define SRC_DSET1 "src_dset1"
+
+#define SRC_ATTR "src_attr"
+
+#define DST_ATTR_ANON_SHORT "dst_attr_anon_short"
+#define DST_ATTR_ANON_INT "dst_attr_anon_int"
+
+#define DST_ATTR "dst_attr"
+#define DST_ATTR2 "dst_attr2"
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_hier_merge
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy:
+ * SRC file:
+ * Create committed datatypes at / and /g0
+ * Create datasets with native type and committed datatypes at /g0
+ * DST file:
+ * Create attributes with anonymous committed datatypes at /uncopied
+ *
+ * Copy / at SRC to DST
+ * Copy /g0 at SRC to DST
+ * Copy the datasets in /g0 at SRC to DST /uncopied
+ * Verify that committed datatypes are copied and merged correctly
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_hier_merge(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t gid = -1; /* Group IDs */
+ hid_t f_tid = -1; /* Datatype ID for root group */
+ hid_t g_tid = -1; /* Datatype ID for group */
+ hid_t anon_tid = -1; /* Anonymous datatype */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ int i; /* Local index variable */
+ hsize_t dim1d[1]; /* dimension sizes */
+ int buf[DIM_SIZE_1]; /* Buffer for data */
+ haddr_t exp_addr_int, exp_addr_short; /* Expected object addresses */
+ H5O_info_t oinfo; /* Object info */
+ char src_filename[NAME_BUF_SIZE]; /* Source file name */
+ char dst_filename[NAME_BUF_SIZE]; /* Destination file name */
+
+ if(reopen)
+ TESTING("H5Ocopy(): hier. of committed datatypes and merging with reopen")
+ else
+ TESTING("H5Ocopy(): hier. of committed datatypes and merging ")
+
+ /* set initial data values */
+ for (i=0; i<DIM_SIZE_1; i++)
+ buf[i] = i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /*
+ * Populate source file
+ */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create and commit committed datatype (int) to root group */
+ if((f_tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, ROOT_NDT_INT, f_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Create group /g0 */
+ if((gid = H5Gcreate2(fid_src, NAME_GROUP_TOP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create and commit committed datatype (short) to group /g0 */
+ if((g_tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, GROUP_NDT_SHORT, g_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create dataset of native int in /g0 */
+ if((did = H5Dcreate2(gid, SRC_DSET1, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* create dataset of committed datatype (short) in /g0 */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET2, g_tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* create dataset of committed datatype (int) in /g0 */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET3, f_tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the datatypes */
+ if(H5Tclose(f_tid) < 0) TEST_ERROR
+ if(H5Tclose(g_tid) < 0) TEST_ERROR
+
+ /* close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create group /uncopied */
+ if((gid = H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create and commit anonymous datatype (short) to /uncopied */
+ if((anon_tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(gid, anon_tid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create attribute of anon ndt (short) in /uncopied */
+ if((aid = H5Acreate2(gid, DST_ATTR_ANON_SHORT, anon_tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(anon_tid) < 0) TEST_ERROR
+
+ /* create and commit anonymous datatype (int) to /uncopied */
+ if((anon_tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(gid, anon_tid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create attribute of anon ndt (int) in /uncopied */
+ if((aid = H5Acreate2(gid, DST_ATTR_ANON_INT, anon_tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(anon_tid) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+ }
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* create ocpl and set merge committed datatype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * Test 1 : copy / in SRC file to DST file
+ */
+ if(H5Ocopy(fid_src, "/", fid_dst, SRC_ROOT_GROUP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* get address of committed datatype at root group */
+ if((tid = H5Topen2(fid_dst, SRC_ROOT_GROUP "/" ROOT_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr_int = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype at /g0 */
+ if((tid = H5Topen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" GROUP_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr_short = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* verify the datatype of first dataset is not committed */
+ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_DSET1, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Tcommitted(tid)) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for second dataset */
+ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for third dataset */
+ if((did = H5Dopen2(fid_dst, SRC_ROOT_GROUP NAME_GROUP_TOP "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Test 2: copy /g0 in SRC to DST
+ */
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP, fid_dst, NAME_GROUP_TOP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* get address of committed datatype at /g0 */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_TOP "/" GROUP_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* verify the datatype of first dataset is not committed */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_DSET1, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Tcommitted(tid)) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for second dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for third dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_TOP "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /*
+ * Test 3: copy datsets in /g0 at SRC to DST group /uncopied
+ */
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_DSET1, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_DSET1, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_NDT_DSET2, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Ocopy(fid_src, NAME_GROUP_TOP "/" SRC_NDT_DSET3, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Open attribute with anon ndt (short), get address */
+ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_UNCOPIED, DST_ATTR_ANON_SHORT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* Open attribute with anon ndt (int), get address */
+ if((aid = H5Aopen_by_name(fid_dst, NAME_GROUP_UNCOPIED, DST_ATTR_ANON_INT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* verify the datatype of first dataset is not committed */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_DSET1, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Tcommitted(tid)) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for second dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_short) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for third dataset */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr_int) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Tclose(tid);
+ H5Tclose(f_tid);
+ H5Tclose(g_tid);
+ H5Tclose(anon_tid);
+ H5Pclose(ocpypl_id);
+ H5Aclose(aid);
+ H5Dclose(did);
+ H5Sclose(sid);
+ H5Gclose(gid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_hier_merge */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_cdt
+ *
+ * Purpose: Tests the "merge committed datatypes" feature of H5Ocopy:
+ * SRC file:
+ * Create committed datatype (short)
+ * Create committed datatype (float)
+ * Create committed datatype (int), with attribute of ndt int
+ * Create committed datatype (double), with attribute of anon ndt short
+ * DST file:
+ * Create committed datatype (int)
+ * Create committed datatype (float), with attribute of native int
+ * Create committed datatype (double), with attribute of anon ndt short
+ *
+ * Copy / at SRC to DST
+ * Verify that committed datatypes are copied and merged correctly
+ *
+ * NOTE:
+ * Comparison of attributes are not implemented yet.
+ * Further tests will be added in the future.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_cdt(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid1 = -1, tid2 = -1; /* Datatype IDs */
+ hid_t tid3 = -1, tid4 = -1; /* Datatype IDs */
+ hid_t tid5 = -1, tid = -1; /* Datatype IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ int i; /* Local index variable */
+ hsize_t dim1d[1]; /* dimension sizes */
+ int buf[DIM_SIZE_1]; /* Buffer for data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object addresses */
+ char src_filename[NAME_BUF_SIZE]; /* Source file name */
+ char dst_filename[NAME_BUF_SIZE]; /* Destination file name */
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging various committed datatypes with reopen")
+ else
+ TESTING("H5Ocopy(): merging various committed datatypes")
+
+ /* set initial data values */
+ for (i=0; i<DIM_SIZE_1; i++)
+ buf[i] = i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /*
+ * Populate source file
+ */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype (short) */
+ if((tid1 = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_SHORT, tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype (float) */
+ if((tid2 = H5Tcopy(H5T_NATIVE_FLOAT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_FLOAT, tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype (int) */
+ if((tid3 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_INT, tid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create an attribute of committed datatype (int); attach to committed datatype (int) */
+ if((aid = H5Acreate2(tid3, SRC_ATTR, tid3, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* create committed datatype (double) */
+ if((tid4 = H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_DOUBLE, tid4, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an anonymous committed datatype (short) */
+ if((tid5 = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(fid_src, tid5, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute of anon ndt (short); attach to committed datatype (double) */
+ if((aid = H5Acreate2(tid4, SRC_ATTR, tid5, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the committed datatypes */
+ if(H5Tclose(tid1) < 0) TEST_ERROR
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid3) < 0) TEST_ERROR
+ if(H5Tclose(tid4) < 0) TEST_ERROR
+ if(H5Tclose(tid5) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype (integer) */
+ if((tid1 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype (float) */
+ if((tid2 = H5Tcopy(H5T_NATIVE_FLOAT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_FLOAT, tid2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute of native integer; attach to committed datatype (float) */
+ if((aid = H5Acreate2(tid2, DST_ATTR, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* create committed datatype (double) */
+ if((tid3 = H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_DOUBLE, tid3, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create anonymous committed datatype (short) */
+ if((tid4 = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit_anon(fid_dst, tid4, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute of anon ndt (short); attach to ndt (double) */
+ if((aid = H5Acreate2(tid3, DST_ATTR, tid4, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the committed datatypes */
+ if(H5Tclose(tid1) < 0) TEST_ERROR
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid3) < 0) TEST_ERROR
+ if(H5Tclose(tid4) < 0) TEST_ERROR
+
+ /* close the dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy everything in SRC to DST */
+ if(H5Ocopy(fid_src, "/", fid_dst, SRC_ROOT_GROUP, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /*
+ * Verification
+ */
+ /* get address of committed datatype: /src_root/src_ndt_double */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /dst_ndt_double */
+ if((tid = H5Topen2(fid_dst, "/" DST_NDT_DOUBLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /src_root/src_ndt_float */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /dst_ndt_float */
+ if((tid = H5Topen2(fid_dst, "/" DST_NDT_FLOAT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /src_root/src_ndt_int */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /dst_ndt_int */
+ if((tid = H5Topen2(fid_dst, "/" DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* get address of committed datatype: /src_root/src_ndt_short */
+ if((tid = H5Topen2(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* open attribute; get its dtype; get dtype's address: /src_root/src_ndt_double/dst_attr */
+ if((aid = H5Aopen_by_name(fid_dst, "/" SRC_ROOT_GROUP "/" SRC_NDT_DOUBLE, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the files */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the object copy property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Pclose(ocpypl_id);
+ H5Tclose(tid);
+ H5Tclose(tid1);
+ H5Tclose(tid2);
+ H5Tclose(tid3);
+ H5Tclose(tid4);
+ H5Tclose(tid5);
+ H5Aclose(aid);
+ H5Sclose(sid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_cdt */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_suggs
+ *
+ * Purpose: Tests the suggested searching paths feature (H5Padd_merge_committed_dtype_path)
+ * is correctly applied in merging the committed datatypes.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /*
+ * Populate source file
+ */
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/src_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/dst_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Create a group /uncopied */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 1
+ */
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/uncopied/src_ndt_int" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/dst_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/uncopied/src_ndt_int" */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 2
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion: "/uncopied/src_ndt_int" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/src_ndt_int" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, SRC_NDT_INT, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/uncopied/src_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/src_ndt_int" */
+ if((tid = H5Topen2(fid_dst, SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 3
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* remove "/uncopied/src_ndt_int" from DST file */
+ if(H5Ldelete(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/uncopied/src_ndt_int" at DST file */
+ /* use default ocpypl_id -- without merging and suggestion */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_int" from SRC file to "/src_ndt_int2" at DST file */
+ /* copy with merging and search suggestion: "/uncopied/src_ndt_int" */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, SRC_NDT_INT2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "/uncopied/src_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/src_ndt_int2" */
+ if((tid = H5Topen2(fid_dst, SRC_NDT_INT2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 4
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, DST_NDT_INT) < 0) TEST_ERROR
+
+ /* copy "src_ndt_int" from SRC file to "/uncopied/src_ndt_int2" at DST file */
+ /* copy with merging and search suggestion: "/dst_ndt_int, /uncopied/src_ndt_int" */
+ if(H5Ocopy(fid_src, SRC_NDT_INT, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "/dst_dt_int", get its address */
+ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of "/uncopied/src_ndt_int2" */
+ if((tid = H5Topen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_INT2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_suggs */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_dset_suggs
+ *
+ * Purpose: Tests the suggested searching paths feature (H5Padd_merge_committed_dtype_path)
+ * is correctly applied in merging the committed datatypes of datasets.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; Dec 12, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_dset_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging committed datatypes of datasets with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging committed datatypes of datasets with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /*
+ * Populate source file
+ */
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/src_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_src, SRC_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0] = DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create dataset */
+ if((did = H5Dcreate2(fid_src, SRC_NDT_DSET, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data to dataset */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* create committed datatype: "/dst_ndt_int" */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Create a group "/uncopied" */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /*
+ * Test 1
+ */
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_dset" from SRC file to "/uncopied/src_ndt_dset" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "/dst_ndt_int", get its address */
+ if((tid = H5Topen2(fid_dst, DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: "/uncopied/src_ndt_dset" */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 2
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion: "/uncopied/src_ndt_dset" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET) < 0) TEST_ERROR
+
+ /* copy "/src_ndt_dset" from SRC file to "/src_ndt_dset" at DST file */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, SRC_NDT_DSET, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype dataset "/uncopied/src_ndt_dset", get its datatype address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: "/src_ndt_dset" */
+ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 3
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* remove "/uncopied/src_ndt_dset" */
+ if(H5Ldelete(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "src_ndt_dset" from SRC file to "/uncopied/src_ndt_dset" at DST file */
+ /* use default ocpypl_id -- without merging and suggestion */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy "src_ndt_dset" from SRC file to "/src_ndt_dset2" at DST file */
+ /* use merging and suggested searching path: "/uncopied/src_ndt_dset" */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, SRC_NDT_DSET2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open the copied dataset: /uncopied/src_ndt_dset", get its address */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: "/src_ndt_dset2" */
+ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 4
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion: "/src_ndt_dset" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, SRC_NDT_DSET) < 0) TEST_ERROR
+
+ /* copy /src_ndt_dset from SRC file to /uncopied/src_ndt_dset2 at DST */
+ /* use merging and suggested search paths: "/src_ndt_dset, /uncopied/src_ndt_dset" */
+ if(H5Ocopy(fid_src, SRC_NDT_DSET, fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open the copied dataset: "/src_ndt_dset", get its datatype address */
+ if((did = H5Dopen2(fid_dst, SRC_NDT_DSET, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* check address of datatype for the copied dataset: /uncopied/src_ndt_dset2 */
+ if((did = H5Dopen2(fid_dst, NAME_GROUP_UNCOPIED "/" SRC_NDT_DSET2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_dset_suggs */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_cdt_merge_all_suggs
+ *
+ * Purpose: Tests the merging committed datatype + search suggestion feature.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_cdt_merge_all_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t gid = -1; /* Group ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t exp_did = -1; /* Dataset ID */
+ hid_t tid_short = -1; /* Datatype ID */
+ hid_t exp_tid; /* Expected datatype ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ if(reopen)
+ TESTING("H5Ocopy(): merging different committed datatypes with suggestions and reopen")
+ else
+ TESTING("H5Ocopy(): merging different committed datatypes with suggestions")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /*
+ * Populate source file
+ */
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* set dataspace dimension, create dataspace */
+ dim1d[0] = DIM_SIZE_1;
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create a group */
+ if((gid = H5Gcreate2(fid_src, SRC_GRP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, SRC_NDT_SHORT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create first dataset in group */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, SRC_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create second dataset in group */
+ if((did = H5Dcreate2(gid, SRC_NDT_DSET2, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create third dataset in group */
+ if((did = H5Dcreate2(gid, SRC_DSET, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* get datatype */
+ if((tid_short = H5Topen2(fid_src, "/" SRC_GRP "/" SRC_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to the dataset */
+ if((aid = H5Acreate2(did, SRC_ATTR, tid_short, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(tid_short) < 0) TEST_ERROR
+
+ /* close the group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* close the dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /*
+ * Populate DST file
+ */
+
+ /* create DST file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* set dataspace dimension, create dataspace */
+ dim1d[0] = DIM_SIZE_2;
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create committed datatype in root group */
+ if((tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_SHORT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create committed datatype in root group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(tid, DST_ATTR, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+
+ /* create committed datatype in root group */
+ if((tid = H5Tcopy(H5T_NATIVE_FLOAT)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_FLOAT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(tid, DST_ATTR, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create a group */
+ if((gid = H5Gcreate2(fid_dst, DST_GRP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create a committed datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((H5Tcommit2(gid, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(gid, DST_ATTR, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create an attribute attached to group */
+ if((aid = H5Acreate2(gid, DST_ATTR2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* create a group */
+ if((gid = H5Gcreate2(fid_dst, DST_GRP2, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create a committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+ if((H5Tcommit2(gid, DST_NDT_INT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to group */
+ if((aid = H5Acreate2(gid, DST_ATTR, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create a committed datatype in group */
+ if((tid = H5Tcopy(H5T_NATIVE_SHORT)) < 0)TEST_ERROR
+ if((H5Tcommit2(gid, DST_NDT_SHORT, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* create a committed datatype at root group */
+ if((tid = H5Tcopy(H5T_NATIVE_DOUBLE)) < 0)TEST_ERROR
+ if((H5Tcommit2(fid_dst, DST_NDT_DOUBLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* get datatype */
+ if((tid_short = H5Topen2(fid_dst, "/" DST_GRP2 "/" DST_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create an attribute attached to committed datatype */
+ if((aid = H5Acreate2(tid, DST_ATTR, tid_short, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ /* closing */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid_short) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 1
+ */
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "A_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* get datatype for attribute attached to the group */
+ if((aid = H5Aopen_by_name(fid_dst, DST_GRP, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Aget_type(aid)) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "A_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 2
+ */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_GRP2) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "B_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* get datatype for attribute attached to the group */
+ if((aid = H5Aopen_by_name(fid_dst, DST_GRP2, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Aget_type(aid)) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "B_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 3
+ */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* add another committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_GRP "/" DST_NDT_INT) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "C_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/dst_grp/dst_dt_int", get its address */
+ if((exp_tid = H5Topen2(fid_dst, "/" DST_GRP "/" DST_NDT_INT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "C_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 4
+ */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* delete the group */
+ if(H5Ldelete(fid_dst, "/" DST_GRP, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* free the search suggestion paths */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset2" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET2, fid_dst, "D_src_dset2", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open datatype of dataset */
+ if((exp_did = H5Dopen2(fid_dst, "A_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Dget_type(exp_did)) < 0) TEST_ERROR
+
+ /* Open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "C_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* open datatype of dataset */
+ if((did = H5Dopen2(fid_dst, "D_src_dset2", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+ if(H5Dclose(exp_did) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 5
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_NDT_DOUBLE) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET, fid_dst, "A_src_dset", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open attribute's dtype attached to committed datatype /dst_ndt_double */
+ if((aid = H5Aopen_by_name(fid_dst, DST_NDT_DOUBLE, DST_ATTR, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((exp_tid = H5Aget_type(aid)) < 0) TEST_ERROR
+
+ /* Open datatype of dataset, check address */
+ if((did = H5Dopen2(fid_dst, "A_src_dset", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Aclose(aid) < 0) TEST_ERROR
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Test 6
+ */
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Add committed datatype search suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/" DST_NDT_SHORT) < 0) TEST_ERROR
+
+ /* copy "/src_grp/src_ndt_dset" from SRC file to DST file */
+ if(H5Ocopy(fid_src, "/" SRC_GRP "/" SRC_NDT_DSET, fid_dst, "B_src_dset", ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* open committed dtype "/dst_ndt_short" */
+ if((exp_tid = H5Topen2(fid_dst, "/" DST_NDT_SHORT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open datatype of dataset, check address */
+ if((did = H5Dopen2(fid_dst, "B_src_dset", H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+
+ /* should be the same */
+ if(!H5Tequal(exp_tid, tid)) TEST_ERROR
+
+ /* closing */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+ if(H5Tclose(exp_tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Tclose(tid_short);
+ H5Tclose(exp_tid);
+ H5Dclose(did);
+ H5Dclose(exp_did);
+ H5Aclose(aid);
+ H5Sclose(sid);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_cdt_merge_all_suggs */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_set_mcdt_search_cb
+ *
+ * Purpose: Tests the "H5Pset_mcdt_search_cb" feature of H5Ocopy to
+ * stop or continue the search of global list
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+/* User data struct for the callback */
+typedef struct mcdt_search_cb_ud {
+ H5O_mcdt_search_ret_t search_action; /* Return value for callback */
+ unsigned called; /* # of times callback has been called */
+} mcdt_search_cb_ud;
+
+/* The user callback function */
+static H5O_mcdt_search_ret_t
+mcdt_search_cb(void *_udata)
+{
+ mcdt_search_cb_ud *udata = (mcdt_search_cb_ud *)_udata;
+
+ udata->called++;
+ return(udata->search_action);
+} /* mcdt_search_cb() */
+
+static int
+test_copy_set_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ H5O_info_t oinfo; /* Object info */
+ haddr_t exp_addr; /* Expected object address */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+ mcdt_search_cb_ud cb_udata; /* User data for callback */
+
+ if(reopen)
+ TESTING("H5Ocopy(): H5Pset_mcdt_search_cb and reopen")
+ else
+ TESTING("H5Ocopy(): H5Pset_mcdt_search_cb")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* named data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied group in destination file */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "a" */
+ if((H5Tcommit2(fid_dst, "/a", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "b" */
+ if((H5Tcommit2(fid_dst, "/b", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy dataset using "/b" as a suggestion, and verify that it uses
+ * datatype "b" in the destination file
+ */
+ /* Add datatype suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/b") < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open dset dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Set callback to continue the search
+ */
+ cb_udata.search_action = H5O_MCDT_SEARCH_CONT;
+ cb_udata.called = 0;
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* Add datatype suggestion to group "/uncopied" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED) < 0) TEST_ERROR
+
+ /* Continue the global search */
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cb, &cb_udata) < 0)
+ TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Verify callback has been called exactly once */
+ if(cb_udata.called != 1) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open copied dataset and its dtype, check address */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE2, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr != exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /*
+ * Stop the search, default action is to create an anonymous committed datatype
+ */
+ cb_udata.search_action = H5O_MCDT_SEARCH_STOP;
+ cb_udata.called = 0;
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Verify callback has been called exactly once */
+ if(cb_udata.called != 1) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /*
+ * Stop the search, default action is to create an anonymous committed datatype.
+ * Disable suggestion list.
+ */
+ cb_udata.search_action = H5O_MCDT_SEARCH_STOP;
+ cb_udata.called = 0;
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Delete dataset */
+ if(H5Ldelete(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Verify callback has been called exactly once */
+ if(cb_udata.called != 1) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Open committed dtype "a", get address */
+ if((tid = H5Topen2(fid_dst, "/a", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Open committed dtype "b", get address */
+ if((tid = H5Topen2(fid_dst, "/b", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ exp_addr = oinfo.addr;
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* Open the copied dataset and get its dtype, addresses should not be equal */
+ if((did = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((tid = H5Dget_type(did)) < 0) TEST_ERROR
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(oinfo.addr == exp_addr) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_set_mcdt_search_cb */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_set_get_mcdt_cb
+ *
+ * Purpose: Tests for the "H5Pset/get_mcdt_search_cb" feature of H5Ocopy.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Vailin Choi; January 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/* The user callback functions */
+static H5O_mcdt_search_ret_t
+mcdt_search_cbA(void *_udata)
+{
+ H5O_mcdt_search_ret_t *action = (H5O_mcdt_search_ret_t *)_udata;
+
+ return(*action);
+} /* mcdt_search_cb() */
+
+static H5O_mcdt_search_ret_t
+mcdt_search_cbB(void *_udata)
+{
+ H5O_mcdt_search_ret_t *action = (H5O_mcdt_search_ret_t *)_udata;
+
+ return(*action);
+} /* mnt_search_cb() */
+
+/* The main test function */
+static int
+test_copy_set_get_mcdt_search_cb(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl,
+ hid_t dst_fapl, hbool_t reopen)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hid_t ocpypl_id = -1; /* Object copy plist ID */
+ unsigned int i; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ int buf[DIM_SIZE_1]; /* Buffer for writing data */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+ H5O_mcdt_search_cb_t mcdt_cb = NULL; /* The callback function */
+ H5O_mcdt_search_ret_t mcdt_udataA; /* User data for callback */
+ H5O_mcdt_search_ret_t mcdt_udataB; /* User data for callback */
+ H5O_mcdt_search_ret_t *mcdt_udata_p = NULL; /* Pointer to user data for callback */
+
+ if(reopen)
+ TESTING("H5Ocopy(): H5Pset/get_mcdt_search_cb and reopen")
+ else
+ TESTING("H5Ocopy(): H5Pset/get_mcdt_search_cb")
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++)
+ buf[i] = (int)i;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], dst_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /*
+ * Populate source file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied group in destination file */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /*
+ * Populate destination file
+ */
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "a" */
+ if((H5Tcommit2(fid_dst, "/a", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)TEST_ERROR
+
+ /* committed data type "b" */
+ if((H5Tcommit2(fid_dst, "/b", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR
+
+ /* Create ocpl and set merge committed dtype flag */
+ if((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) TEST_ERROR
+ if(H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG) < 0) TEST_ERROR
+
+ /*
+ * First copy dataset using "/b" as a suggestion, and verify that it uses
+ * datatype "b" in the destination file
+ */
+ /* Add datatype suggestion */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, "/b") < 0) TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != NULL) TEST_ERROR
+ if(mcdt_udata_p != NULL) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /*
+ * Set callback to continue the search
+ */
+ mcdt_udataA = H5O_MCDT_SEARCH_CONT;
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ /* Add datatype suggestion to group "/uncopied" */
+ if(H5Padd_merge_committed_dtype_path(ocpypl_id, NAME_GROUP_UNCOPIED) < 0) TEST_ERROR
+
+ /* Continue the global search */
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cbA, &mcdt_udataA) < 0)
+ TEST_ERROR
+
+ /* open the destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE2, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ mcdt_cb = NULL;
+ mcdt_udata_p = NULL;
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != mcdt_search_cbA) TEST_ERROR
+ if(mcdt_udata_p != &mcdt_udataA) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /*
+ * Stop the search, default action is to create an anonymous committed datatype
+ */
+ mcdt_udataB = H5O_MCDT_SEARCH_STOP;
+
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cbA, &mcdt_udataB) < 0)
+ TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ mcdt_cb = NULL;
+ mcdt_udata_p = NULL;
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != mcdt_search_cbA) TEST_ERROR
+ if(mcdt_udata_p != &mcdt_udataB) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* Free suggestions */
+ if(H5Pfree_merge_committed_dtype_paths(ocpypl_id) < 0) TEST_ERROR
+
+ if(H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cbB, &mcdt_udataB) < 0)
+ TEST_ERROR
+
+ /* open destination file */
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Delete dataset */
+ if(H5Ldelete(fid_dst, NAME_DATASET_SIMPLE3, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* copy SRC dset to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE3, ocpypl_id, H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(reopen) {
+ /* Reopen file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+ if((fid_dst = H5Fopen(dst_filename, H5F_ACC_RDONLY, dst_fapl)) < 0) TEST_ERROR
+ } /* end if */
+
+ mcdt_cb = NULL;
+ mcdt_udata_p = NULL;
+
+ /* Verify "get" routine functionality */
+ if(H5Pget_mcdt_search_cb(ocpypl_id, &mcdt_cb, (void **) &mcdt_udata_p) < 0) TEST_ERROR
+
+ if(mcdt_cb != mcdt_search_cbB) TEST_ERROR
+ if(mcdt_udata_p != &mcdt_udataB) TEST_ERROR
+
+ /* Close destination file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close property list */
+ if(H5Pclose(ocpypl_id) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid_src);
+ H5Fclose(fid_dst);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Dclose(did);
+ H5Pclose(ocpypl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_set_get_mcdt_search_cb */
+
+
+/*-------------------------------------------------------------------------
* Function: test_copy_option
*
* Purpose: Create a group in SRC file and copy it to DST file
@@ -8727,6 +11916,7 @@ main(void)
unsigned max_compact, min_dense;
int configuration; /* Configuration of tests. */
int ExpressMode;
+ hbool_t same_file; /* Whether to run tests that only use one file */
/* Setup */
h5_reset();
@@ -8759,6 +11949,11 @@ main(void)
hid_t fcpl_src;
hid_t fcpl_dst;
+ /* Start with same_file == TRUE. Use source file settings for these
+ * tests. Don't run with a non-default destination file setting, as
+ * destination settings have no effect. */
+ same_file = TRUE;
+
/* No need to test dense attributes with old format */
if(!(configuration & CONFIG_SRC_NEW_FORMAT) && (configuration & CONFIG_DENSE))
continue;
@@ -8775,6 +11970,7 @@ main(void)
if(configuration & CONFIG_SHARE_DST) {
puts("Testing with shared dst messages:");
fcpl_dst = fcpl_shared;
+ same_file = FALSE;
}
else {
puts("Testing without shared dst messages:");
@@ -8797,7 +11993,7 @@ main(void)
}
} /* end if */
else {
- puts("Testing with oldest file format for source file:");
+ puts("Testing with oldest file format for source file:");
src_fapl = fapl;
num_attributes_g = 4;
} /* end else */
@@ -8806,6 +12002,7 @@ main(void)
if(configuration & CONFIG_DST_NEW_FORMAT) {
puts("Testing with latest format for destination file:");
dst_fapl = fapl2;
+ same_file = FALSE;
} /* end if */
else {
puts("Testing with oldest file format for destination file:");
@@ -8873,10 +12070,32 @@ main(void)
/* Tests that do not use attributes and do not need to be tested
* multiple times for different attribute configurations */
if(configuration < CONFIG_DENSE) {
+ hbool_t reopen;
+
nerrors += test_copy_named_datatype(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_named_datatype_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_named_datatype_vl_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
+ /* Loop over reopening the file */
+ for(reopen = FALSE; reopen <= TRUE; reopen++) {
+ nerrors += test_copy_committed_datatype_merge(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+
+ if(same_file)
+ nerrors += test_copy_committed_datatype_merge_same_file(fcpl_src, src_fapl, reopen);
+
+ nerrors += test_copy_committed_dt_merge_sugg(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_committed_dt_merge_attr(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+
+ /* tests added for merging committed datatypes + suggestions + callback */
+ nerrors += test_copy_cdt_hier_merge(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_cdt(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_suggs(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_dset_suggs(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_cdt_merge_all_suggs(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_set_mcdt_search_cb(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ nerrors += test_copy_set_get_mcdt_search_cb(fcpl_src, fcpl_dst, src_fapl, dst_fapl, reopen);
+ } /* end for */
+
nerrors += test_copy_dataset_external(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_named_dtype(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_named_dtype_hier(fcpl_src, fcpl_dst, src_fapl, dst_fapl);