summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-06-26 22:01:43 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-06-26 22:01:43 (GMT)
commit8d72542a50fac7a747fe0bfec8d2285de8efd29f (patch)
treeda26f38920601ae4274e77d3363767ca057a66ab /src
parent785938ace19e2533ab94c14b6cd8de508fe18f15 (diff)
downloadhdf5-8d72542a50fac7a747fe0bfec8d2285de8efd29f.zip
hdf5-8d72542a50fac7a747fe0bfec8d2285de8efd29f.tar.gz
hdf5-8d72542a50fac7a747fe0bfec8d2285de8efd29f.tar.bz2
[svn-r12439] Purpose:
New feature Description: Check in Peter's code to add support for "shallow copy", "create intermediate groups", "no attributes" and "expand soft links" support. Platforms tested: FreeBSD 4.11 (sleipnir) Linux 2.4 (chicago) w/ & w/o group-revision enabled h5committest
Diffstat (limited to 'src')
-rw-r--r--src/H5Dcontig.c3
-rw-r--r--src/H5G.c35
-rw-r--r--src/H5Gnode.c50
-rw-r--r--src/H5Gpkg.h10
-rw-r--r--src/H5Gprivate.h2
-rw-r--r--src/H5Gpublic.h14
-rw-r--r--src/H5O.c112
-rw-r--r--src/H5Oattr.c49
-rw-r--r--src/H5Ocont.c4
-rw-r--r--src/H5Odtype.c12
-rw-r--r--src/H5Oefl.c4
-rw-r--r--src/H5Olayout.c4
-rw-r--r--src/H5Olinfo.c55
-rw-r--r--src/H5Olink.c103
-rw-r--r--src/H5Opkg.h7
-rw-r--r--src/H5Opline.c8
-rw-r--r--src/H5Oprivate.h15
-rw-r--r--src/H5Oshared.c28
-rw-r--r--src/H5Ostab.c23
19 files changed, 412 insertions, 126 deletions
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 97fd043..09af474 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -990,6 +990,9 @@ done:
* Programmer: Quincey Koziol
* Monday, November 21, 2005
*
+ * Modifier: Peter Cao
+ * Saturday, January 07, 2006
+ * Add case to deal with compressed variable length datasets
*-------------------------------------------------------------------------
*/
herr_t
diff --git a/src/H5G.c b/src/H5G.c
index e66825b..34d3c56 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -2356,7 +2356,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_get_objinfo(H5G_loc_t *loc, const char *name, hbool_t follow_link,
+H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link,
H5G_stat_t *statbuf/*out*/, hid_t dxpl_id)
{
H5G_trav_ud4_t udata; /* User data for callback */
@@ -2999,17 +2999,17 @@ H5G_unmount(H5G_t *grp)
static herr_t
H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t plist_id)
{
- H5P_genplist_t *gcrt_plist = NULL; /* Group create property list created */
- H5P_genplist_t *gcpy_plist; /* Group copy property list created */
- hid_t dxpl_id = H5AC_dxpl_id;
+ H5P_genplist_t *gcrt_plist=NULL; /* Group create property list created */
+ H5P_genplist_t *gcpy_plist=NULL; /* Group 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 */
- hbool_t entry_inserted = FALSE; /* Flag to indicate that the new entry was inserted into a group */
+ hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */
+ hbool_t gcrt_plist_created=FALSE; /* Flag to indicate if H5G_CREATE_INTERMEDIATE_GROUP_FLAG is set */
unsigned cpy_option = 0; /* Copy options */
H5P_genclass_t *gcrt_class; /* Group creation property class */
- hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */
- hbool_t gcplist_created = FALSE; /* Flag o indicate if group creation property list is created */
+ hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_copy, FAIL);
@@ -3041,22 +3041,26 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t pli
/* Create group creatiion property to create missing groups */
if((cpy_option & H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG) > 0) {
if(NULL == (gcrt_class = H5I_object_verify(H5P_GROUP_CREATE, H5I_GENPROP_CLS)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
/* Create the new property list */
if((gcplist_id = H5P_create_id(gcrt_class)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list");
- gcplist_created = TRUE;
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list")
+ gcrt_plist_created = TRUE;
} else
gcplist_id = H5P_GROUP_CREATE_DEFAULT;
+ /* Get a pointer to the group creation property list */
if(NULL == (gcrt_plist = H5I_object(gcplist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Set the intermediate group creation property, if requested */
- if(gcplist_created)
- if(H5P_set(gcrt_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &cpy_option) < 0)
+ if(gcrt_plist_created) {
+ unsigned crt_intmd_group = TRUE;
+
+ if(H5P_set(gcrt_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set intermediate group creation flag")
+ } /* end if */
/* Insert the new object in the destination file's group */
if(H5G_insert(dst_loc, dst_name, &new_loc, dxpl_id, gcrt_plist) < 0)
@@ -3067,8 +3071,11 @@ done:
/* Free the ID to name buffers */
if(entry_inserted)
H5G_loc_free(&new_loc);
- if (gcplist_created)
- H5P_close(gcrt_plist);
+
+ if(gcplist_id>0 && gcrt_plist_created) {
+ if(H5I_dec_ref(gcplist_id)<0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement ref count on property list")
+ }
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_copy() */
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 126be95..d6915ea 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -1907,6 +1907,8 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
const void UNUSED *_rt_key, void *_udata)
{
H5G_bt_it_ud5_t *udata = (H5G_bt_it_ud5_t *)_udata;
+ H5O_loc_t *parent_src_oloc = udata->src_oloc;
+ H5O_copy_t *cpy_info = udata->cpy_info;
const H5HL_t *heap = NULL;
H5G_node_t *sn = NULL;
unsigned int i; /* Local index variable */
@@ -1930,17 +1932,50 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
/* copy object in this node one by one */
for(i = 0; i < sn->nsyms; i++) {
H5G_entry_t *src_ent = &(sn->entry[i]); /* Convenience variable to refer to current source group entry */
- H5O_loc_t new_oloc; /* Copied object object location */
H5O_link_t lnk; /* Link to insert */
const char *name; /* Name of source object */
-
- /* Set up copied object location to fill in */
- H5O_loc_reset(&new_oloc);
- new_oloc.file = udata->dst_file;
+ H5G_entry_t tmp_src_ent; /* Temperary copy. Change will not affect the cache */
+
+ /* expand soft link */
+ if(H5G_CACHED_SLINK == src_ent->type && cpy_info->expand_soft_link) {
+ H5G_stat_t statbuf; /* Information about object pointed to by soft link */
+ H5G_loc_t grp_loc; /* Group location for parent of soft link */
+ H5G_name_t grp_path; /* Path for parent of soft link */
+ char *link_name; /* Pointer to value of soft link */
+
+ /* Make a temporary copy, so that it will not change the info in the cache */
+ HDmemcpy(&tmp_src_ent, src_ent, sizeof(H5G_entry_t));
+ src_ent = &tmp_src_ent;
+
+ /* Set up group location for soft link to start in */
+ H5G_name_reset(&grp_path);
+ grp_loc.path = &grp_path;
+ grp_loc.oloc = parent_src_oloc;
+
+ /* Get pointer to link value in local heap */
+ link_name = (char *)H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset);
+
+ /* Check if the object pointed by the soft link exists in the source file */
+ /* (It would be more efficient to make a specialized traversal callback,
+ * but this is good enough for now... -QAK)
+ */
+ if(H5G_get_objinfo(&grp_loc, link_name, TRUE, &statbuf, H5AC_ind_dxpl_id) >= 0) {
+#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG
+ src_ent->header = (((haddr_t)statbuf.objno[1]) << (8 * sizeof(long))) | (haddr_t)statbuf.objno[0];
+#else
+ src_ent->header = statbuf.objno[0];
+#endif
+ } /* end if */
+ } /* if ((H5G_CACHED_SLINK == src_ent->type)... */
/* Check if object in source group is a hard link */
if(H5F_addr_defined(src_ent->header)) {
- H5O_loc_t src_oloc; /* Temporary object location for source object */
+ H5O_loc_t new_oloc; /* Copied object object location */
+ H5O_loc_t src_oloc; /* Temporary object location for source object */
+
+ /* Set up copied object location to fill in */
+ H5O_loc_reset(&new_oloc);
+ new_oloc.file = udata->dst_file;
/* Build temporary object location for source */
src_oloc.file = f;
@@ -1948,8 +1983,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
src_oloc.addr = src_ent->header;
/* Copy the shared object from source to destination */
- /* (Increments link count on destination) */
- if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, udata->cpy_option, udata->map_list) < 0)
+ if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, cpy_info, TRUE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5B_ITER_ERROR, "unable to copy object")
/* Construct link information for eventual insertion */
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index c8db6e3..98e3516 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -224,11 +224,11 @@ typedef struct H5G_bt_it_ud4_t {
/* Data passed to B-tree iteration for copying copy symblol table content */
typedef struct H5G_bt_it_ud5_t {
- haddr_t src_heap_addr; /* heap address of the source symbol table */
- H5F_t *dst_file; /* File of destination group */
- H5O_stab_t *dst_stab; /* symbol table info for destination group */
- H5SL_t *map_list; /* skip list to map copied object addresses */
- unsigned cpy_option; /* cpy options */
+ H5O_loc_t *src_oloc; /* source object location */
+ haddr_t src_heap_addr; /* heap address of the source symbol table */
+ H5F_t *dst_file; /* File of destination group */
+ H5O_stab_t *dst_stab; /* symbol table info for destination group */
+ H5O_copy_t *cpy_info; /* Information for copy operation */
} H5G_bt_it_ud5_t;
/* Typedef for path traversal operations */
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index d3b00e3..e498671 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -130,7 +130,7 @@ H5_DLL H5G_t *H5G_open(H5G_loc_t *loc, hid_t dxpl_id);
H5_DLL herr_t H5G_close(H5G_t *grp);
H5_DLL herr_t H5G_insert(H5G_loc_t *loc, const char *name,
H5G_loc_t *obj_loc, hid_t dxpl_id, struct H5P_genplist_t *oc_plist);
-H5_DLL herr_t H5G_get_objinfo(H5G_loc_t *loc, const char *name,
+H5_DLL herr_t H5G_get_objinfo(const H5G_loc_t *loc, const char *name,
hbool_t follow_link, H5G_stat_t *statbuf/*out*/, hid_t dxpl_id);
H5_DLL H5F_t *H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id);
H5_DLL herr_t H5G_free_grp_name(H5G_t *grp);
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index 361c85d..fd322a6 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -115,13 +115,13 @@ typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name,
void *op_data);
/* Flags for object copy (H5Gcopy) */
-#define H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG (0x0001u) /* Create missing groups when create a group */
-#define H5G_COPY_SHALLOW_HIERARCHY_FLAG (0x0002u) /* Copy only immediate members */
-#define H5G_COPY_EXPAND_SOFT_LINK_FLAG (0x0004u) /* Expand soft links into new objects */
-#define H5G_COPY_EXPAND_EXT_LINK_FLAG (0x0008u) /* Expand external links into new objects */
-#define H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG (0x0010u) /* Copy objects that are pointed by references */
-#define H5G_COPY_WITHOUT_ATTR_FLAG (0x0020u) /* Copy object without copying attributes */
-#define H5G_COPY_ALL (0x003Fu) /* All object copying flags (for internal range checking) */
+#define H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG (0x0001u) /* Create missing groups when create a group */
+#define H5G_COPY_SHALLOW_HIERARCHY_FLAG (0x0002u) /* Copy only immediate members */
+#define H5G_COPY_EXPAND_SOFT_LINK_FLAG (0x0004u) /* Expand soft links into new objects */
+#define H5G_COPY_EXPAND_EXT_LINK_FLAG (0x0008u) /* Expand external links into new objects */
+#define H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG (0x0010u) /* Copy objects that are pointed by references */
+#define H5G_COPY_WITHOUT_ATTR_FLAG (0x0020u) /* Copy object without copying attributes */
+#define H5G_COPY_ALL (0x003Fu) /* All object copying flags (for internal checking) */
H5_DLL hid_t H5Gcreate(hid_t loc_id, const char *name, size_t size_hint);
H5_DLL hid_t H5Gopen(hid_t loc_id, const char *name);
diff --git a/src/H5O.c b/src/H5O.c
index 632337d..18eee25 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -222,9 +222,9 @@ static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type
static H5G_obj_t H5O_obj_type_real(H5O_t *oh);
static const H5O_obj_class_t *H5O_obj_class(H5O_t *oh);
static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *mesg_src,
- H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
+ H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list);
+ hid_t dxpl_id, H5O_copy_t *cpy_info);
static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
@@ -4034,7 +4034,7 @@ H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5_copy_depth_t depth)
*/
static void *
H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata)
+ H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata)
{
void *ret_value;
@@ -4046,9 +4046,9 @@ H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *native_sr
HDassert(file_src);
HDassert(native_src);
HDassert(file_dst);
- HDassert(map_list);
+ HDassert(cpy_info);
- if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, dxpl_id, cpy_option, map_list, udata)))
+ if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, dxpl_id, cpy_info, udata)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy object header message to file")
done:
@@ -4070,7 +4070,7 @@ done:
*/
static herr_t
H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list)
+ hid_t dxpl_id, H5O_copy_t *cpy_info)
{
H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
H5O_t *oh_src = NULL; /* Object header for source object */
@@ -4083,7 +4083,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
const H5O_msg_class_t *copy_type; /* Type of message to use for copying */
const H5O_obj_class_t *obj_class; /* Type of object we are copying */
void *udata = NULL; /* User data for passing to message callbacks */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5O_copy_header_real)
@@ -4091,7 +4091,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(oloc_src->file);
HDassert(H5F_addr_defined(oloc_src->addr));
HDassert(oloc_dst->file);
- HDassert(map_list);
+ HDassert(cpy_info);
/* Get source object header */
if(NULL == (oh_src = H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ)))
@@ -4198,6 +4198,8 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(copy_type);
if(copy_type->pre_copy_file) {
+ hbool_t deleted = FALSE; /* Flag to indicate that the message should be deleted from the destination */
+
/*
* Decode the message if necessary. If the message is shared then do
* a shared message, ignoring the message type.
@@ -4210,8 +4212,23 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
} /* end if (NULL == mesg_src->native) */
/* Perform "pre copy" operation on messge */
- if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->type, mesg_src->native, udata) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
+ if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->type, mesg_src->native, &deleted, cpy_info, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'pre copy' operation on message")
+
+ /* Check if the message should be deleted in the destination */
+ if(deleted) {
+ /* Change ID of destination message to NULL */
+ mesg_dst->type = H5O_MSG_NULL;
+
+ /* Clear message data to 0 */
+ HDmemset(mesg_dst->raw, 0, mesg_dst->raw_size);
+
+ /* Clear message flags */
+ mesg_dst->flags = 0;
+
+ /* Mark message as dirty */
+ mesg_dst->dirty = TRUE;
+ } /* end if */
} /* end if */
} /* end for */
@@ -4222,10 +4239,13 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
mesg_dst = &(oh_dst->mesg[mesgno]);
/* Check for shared message to operate on */
- if (mesg_src->flags & H5O_FLAG_SHARED)
+ /* (Use destination message, in case the message has been removed (i.e
+ * converted to a nil message) in the destination -QAK)
+ */
+ if (mesg_dst->flags & H5O_FLAG_SHARED)
copy_type = H5O_MSG_SHARED;
else
- copy_type = mesg_src->type;
+ copy_type = mesg_dst->type;
/* copy this message into destination file */
HDassert(copy_type);
@@ -4244,12 +4264,12 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* Copy the source message */
if(H5O_CONT_ID == mesg_src->type->id) {
if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
- oloc_dst->file, dxpl_id, cpy_option, map_list, oh_dst->chunk)) == NULL)
+ oloc_dst->file, dxpl_id, cpy_info, oh_dst->chunk)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
} /* end if */
else {
if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
- oloc_dst->file, dxpl_id, cpy_option, map_list, udata)) == NULL)
+ oloc_dst->file, dxpl_id, cpy_info, udata)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
} /* end else */
@@ -4278,7 +4298,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
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 */
- if(H5SL_insert(map_list, addr_map, &(addr_map->src_addr)) < 0)
+ if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_addr)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
/* "post copy" loop over messages, to fix up any messages which require a complete
@@ -4287,27 +4307,30 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
/* Set up convenience variables */
mesg_src = &(oh_src->mesg[mesgno]);
+ mesg_dst = &(oh_dst->mesg[mesgno]);
/* Check for shared message to operate on */
- if(mesg_src->flags & H5O_FLAG_SHARED)
+ /* (Use destination message, in case the message has been removed (i.e
+ * converted to a nil message) in the destination -QAK)
+ */
+ if(mesg_dst->flags & H5O_FLAG_SHARED)
copy_type = H5O_MSG_SHARED;
else
- copy_type = mesg_src->type;
+ copy_type = mesg_dst->type;
HDassert(copy_type);
if(copy_type->post_copy_file && mesg_src->native) {
hbool_t modified = FALSE;
/* Get destination message */
- mesg_dst = &(oh_dst->mesg[mesgno]);
HDassert(mesg_dst->type == mesg_src->type);
/* Make certain the destination's native info is available */
LOAD_NATIVE(oloc_dst->file, dxpl_id, mesg_dst, FAIL)
/* Perform "post copy" operation on messge */
- if((copy_type->post_copy_file)(oloc_src->file, mesg_src->native, oloc_dst,
- mesg_dst->native, &modified, dxpl_id, cpy_option, map_list) < 0)
+ if((copy_type->post_copy_file)(oloc_src, mesg_src->native, oloc_dst,
+ mesg_dst->native, &modified, dxpl_id, cpy_info) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
/* Mark message and header as dirty if the destination message was modified */
@@ -4369,7 +4392,7 @@ done:
*/
herr_t
H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list)
+ hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth)
{
H5O_addr_map_t *addr_map; /* Address mapping of object copied */
hbool_t inc_link; /* Whether to increment the link count for the object */
@@ -4381,19 +4404,28 @@ H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
HDassert(oloc_src);
HDassert(oloc_dst);
HDassert(oloc_dst->file);
- HDassert(map_list);
+ HDassert(cpy_info);
/* Look up the address of the object to copy in the skip list */
- addr_map = (H5O_addr_map_t *)H5SL_search(map_list, &(oloc_src->addr));
+ addr_map = (H5O_addr_map_t *)H5SL_search(cpy_info->map_list, &(oloc_src->addr));
/* Check if address is already in list of objects copied */
if(addr_map == NULL) {
/* Copy object for the first time */
+ /* Check for incrementing the depth of copy */
+ /* (Can't do this for all copies, since shared datatypes should always be copied) */
+ if(inc_depth)
+ cpy_info->curr_depth++;
+
/* Copy object referred to */
- if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, cpy_option, map_list) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, cpy_info) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+ /* Check for incrementing the depth of copy */
+ if(inc_depth)
+ cpy_info->curr_depth--;
+
/* When an object is copied for the first time, increment it's link */
inc_link = TRUE;
} /* end if */
@@ -4470,10 +4502,10 @@ H5O_copy_free_addrmap_cb(void *item, void UNUSED *key, void UNUSED *op_data)
*-------------------------------------------------------------------------
*/
herr_t
-H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id,
- unsigned cpy_option)
+H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
+ hid_t dxpl_id, unsigned cpy_option)
{
- H5SL_t *map_list = NULL; /* Skip list to hold address mappings */
+ H5O_copy_t cpy_info; /* Information for copying object */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5O_copy_header, FAIL)
@@ -4483,17 +4515,35 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t d
HDassert(H5F_addr_defined(oloc_src->addr));
HDassert(oloc_dst->file);
+ /* Convert copy flags into copy struct */
+ HDmemset(&cpy_info, 0, sizeof(H5O_copy_t));
+ if((cpy_option & H5G_COPY_SHALLOW_HIERARCHY_FLAG) > 0) {
+ cpy_info.copy_shallow = TRUE;
+ cpy_info.max_depth = 1;
+ } /* end if */
+ else
+ cpy_info.max_depth = -1; /* Current default is for full, recursive hier. copy */
+ cpy_info.curr_depth = 0;
+ if((cpy_option & H5G_COPY_EXPAND_SOFT_LINK_FLAG) > 0)
+ cpy_info.expand_soft_link = TRUE;
+ if((cpy_option & H5G_COPY_EXPAND_EXT_LINK_FLAG) > 0)
+ cpy_info.expand_ext_link = TRUE;
+ if((cpy_option & H5G_COPY_EXPAND_OBJ_REFERENCE_FLAG) > 0)
+ cpy_info.expand_obj_ref = TRUE;
+ if((cpy_option & H5G_COPY_WITHOUT_ATTR_FLAG) > 0)
+ cpy_info.copy_without_attr = TRUE;
+
/* Create a skip list to keep track of which objects are copied */
- if((map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, 16)) == NULL)
+ if((cpy_info.map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, 16)) == NULL)
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
- if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, cpy_option, map_list) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, &cpy_info) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
done:
- if(map_list)
- H5SL_destroy(map_list, H5O_copy_free_addrmap_cb, NULL);
+ if(cpy_info.map_list)
+ H5SL_destroy(cpy_info.map_list, H5O_copy_free_addrmap_cb, NULL);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_copy_header() */
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index eefc28b..d13216b 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -37,8 +37,10 @@ static herr_t H5O_attr_reset (void *_mesg);
static herr_t H5O_attr_free (void *mesg);
static herr_t H5O_attr_delete (H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
+static herr_t H5O_attr_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type,
+ void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
static void *H5O_attr_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
+ H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
static herr_t H5O_attr_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -57,7 +59,7 @@ const H5O_msg_class_t H5O_MSG_ATTR[1] = {{
H5O_attr_link, /* link method */
NULL, /* get share method */
NULL, /* set share method */
- NULL, /* pre copy native value to file */
+ H5O_attr_pre_copy_file, /* pre copy native value to file */
H5O_attr_copy_file, /* copy native value to file */
NULL, /* post copy native value to file */
H5O_attr_debug /* debug the message */
@@ -635,6 +637,42 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_attr_pre_copy_file
+ *
+ * Purpose: Perform any necessary actions before copying message between
+ * files for attribute messages.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, June 26, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_attr_pre_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *type,
+ void UNUSED *native_src, hbool_t *deleted, const H5O_copy_t *cpy_info,
+ void UNUSED *udata)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_pre_copy_file)
+
+ /* check args */
+ HDassert(deleted);
+ HDassert(cpy_info);
+
+ /* If we are not copying attributes into the destination file, indicate
+ * that this message should be deleted.
+ */
+ if(cpy_info->copy_without_attr)
+ *deleted = TRUE;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_attr_pre_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_attr_copy_file
*
* Purpose: Copies a message from _MESG to _DEST in file
@@ -654,7 +692,7 @@ done:
*/
static void *
H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void UNUSED *udata)
+ hid_t dxpl_id, H5O_copy_t *cpy_info, void UNUSED *udata)
{
H5A_t *attr_src = (H5A_t *)native_src;
H5A_t *attr_dst = NULL;
@@ -674,7 +712,8 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
/* check args */
HDassert(attr_src);
HDassert(file_dst);
- HDassert(map_list);
+ HDassert(cpy_info);
+ HDassert(!cpy_info->copy_without_attr);
/* Allocate space for the destination message */
if(NULL == (attr_dst = H5FL_CALLOC(H5A_t)))
@@ -718,7 +757,7 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
dst_oloc->file = file_dst;
/* Copy the shared object from source to destination */
- if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_option, map_list) < 0)
+ if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
/* Reset shared message information */
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index c4c8af3..6cb5735 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -42,7 +42,7 @@ static size_t H5O_cont_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_cont_free(void *mesg);
static herr_t H5O_cont_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static void *H5O_cont_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
+ hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
static herr_t H5O_cont_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -260,7 +260,7 @@ done:
*/
static void *
H5O_cont_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t UNUSED *file_dst,
- hid_t UNUSED dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void *udata)
+ hid_t UNUSED dxpl_id, H5O_copy_t UNUSED *cpy_info, void *udata)
{
H5O_cont_t *cont_src = (H5O_cont_t *) mesg_src;
H5O_chunk_t *chunk = (H5O_chunk_t *)udata;
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 9f44924..93470c5 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -32,13 +32,13 @@ static size_t H5O_dtype_size (const H5F_t *f, const void *_mesg);
static herr_t H5O_dtype_reset (void *_mesg);
static herr_t H5O_dtype_free (void *_mesg);
static herr_t H5O_dtype_get_share (H5F_t *f, const void *_mesg,
- H5O_shared_t *sh);
+ H5O_shared_t *sh);
static herr_t H5O_dtype_set_share (H5F_t *f, void *_mesg,
- const H5O_shared_t *sh);
+ const H5O_shared_t *sh);
static herr_t H5O_dtype_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type,
- void *mesg_src, void *_udata);
+ void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
static herr_t H5O_dtype_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg,
- FILE * stream, int indent, int fwidth);
+ FILE * stream, int indent, int fwidth);
/* This message derives from H5O message class */
const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
@@ -1216,7 +1216,9 @@ H5O_dtype_set_share(H5F_t UNUSED *f, void *_mesg/*in,out*/,
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_dtype_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type, void *mesg_src, void *_udata)
+H5O_dtype_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type,
+ void *mesg_src, hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info,
+ void *_udata)
{
H5T_t *dt_src = (H5T_t *)mesg_src; /* Source datatype */
H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 2fef999..afa46f1 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -34,7 +34,7 @@ static void *H5O_efl_copy(const void *_mesg, void *_dest, unsigned update_flags)
static size_t H5O_efl_size(const H5F_t *f, 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,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
+ hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
static herr_t H5O_efl_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -436,7 +436,7 @@ done:
*/
static void *
H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
- hid_t dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void UNUSED *_udata)
+ hid_t dxpl_id, H5O_copy_t UNUSED *cpy_info, void UNUSED *_udata)
{
H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src;
H5O_efl_t *efl_dst = NULL;
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index ffebfc6..b6008c8 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -40,7 +40,7 @@ static herr_t H5O_layout_reset(void *_mesg);
static herr_t H5O_layout_free(void *_mesg);
static herr_t H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static void *H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
+ hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
static herr_t H5O_layout_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -622,7 +622,7 @@ done:
*/
static void *
H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxpl_id,
- UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void *_udata)
+ H5O_copy_t UNUSED *cpy_info, void *_udata)
{
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 a14be2a..1b84191 100644
--- a/src/H5Olinfo.c
+++ b/src/H5Olinfo.c
@@ -40,6 +40,8 @@ static herr_t H5O_linfo_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_linfo_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_linfo_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_linfo_free(void *_mesg);
+static void *H5O_linfo_copy_file(H5F_t *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
static herr_t H5O_linfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -59,7 +61,7 @@ const H5O_msg_class_t H5O_MSG_LINFO[1] = {{
NULL, /*get share method */
NULL, /*set share method */
NULL, /* pre copy native value to file */
- NULL, /* copy native value to file */
+ H5O_linfo_copy_file, /* copy native value to file */
NULL, /* post copy native value to file */
H5O_linfo_debug /*debug the message */
}};
@@ -266,6 +268,57 @@ H5O_linfo_free(void *mesg)
/*-------------------------------------------------------------------------
+ * Function: H5O_linfo_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * June 26, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_linfo_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_dst,
+ hid_t UNUSED dxpl_id, H5O_copy_t *cpy_info, void UNUSED *udata)
+{
+ H5O_linfo_t *linfo_src = (H5O_linfo_t *) native_src;
+ H5O_linfo_t *linfo_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_linfo_copy_file)
+
+ /* check args */
+ HDassert(linfo_src);
+ HDassert(cpy_info);
+
+ /* Copy the source message */
+ if(NULL == (linfo_dst = H5O_linfo_copy(linfo_src, NULL, FALSE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "memory allocation failed")
+
+ /* If we are performing a 'shallow hierarchy' copy, and the links in this
+ * group won't be included in the destination, reset the link count for
+ * this group.
+ */
+ if(cpy_info->max_depth >= 0 && cpy_info->curr_depth >= cpy_info->max_depth)
+ linfo_dst->nlinks = 0;
+
+ /* Set return value */
+ ret_value = linfo_dst;
+
+done:
+ if(!ret_value)
+ if(linfo_dst)
+ H5FL_FREE(H5O_linfo_t, linfo_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_linfo_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_linfo_debug
*
* Purpose: Prints debugging info for a message.
diff --git a/src/H5Olink.c b/src/H5Olink.c
index 464f96b..bc45326 100644
--- a/src/H5Olink.c
+++ b/src/H5Olink.c
@@ -43,12 +43,14 @@ static size_t H5O_link_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_link_reset(void *_mesg);
static herr_t H5O_link_free(void *_mesg);
static herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
+static herr_t H5O_link_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type,
+ 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, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
-static herr_t H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hbool_t *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list);
+ H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
+static herr_t H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
+ void *mesg_dst, hbool_t *modified, 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);
+ FILE * stream, int indent, int fwidth);
/* This message derives from H5O message class */
const H5O_msg_class_t H5O_MSG_LINK[1] = {{
@@ -65,7 +67,7 @@ const H5O_msg_class_t H5O_MSG_LINK[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- NULL, /* pre copy native value to file */
+ H5O_link_pre_copy_file, /* pre copy native value to file */
H5O_link_copy_file, /* copy native value to file */
H5O_link_post_copy_file, /* post copy native value to file */
H5O_link_debug /*debug the message */
@@ -463,6 +465,44 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_link_pre_copy_file
+ *
+ * Purpose: Perform any necessary actions before copying message between
+ * files for link messages.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, June 26, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_pre_copy_file(H5F_t UNUSED *file_src, const H5O_msg_class_t UNUSED *type,
+ void UNUSED *native_src, hbool_t *deleted, const H5O_copy_t *cpy_info,
+ void UNUSED *udata)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_pre_copy_file)
+
+ /* check args */
+ HDassert(deleted);
+ HDassert(cpy_info);
+
+ /* If we are performing a 'shallow hierarchy' copy, and this link won't
+ * be included in the final group, indicate that it should be deleted
+ * in the destination object header before performing any other actions
+ * on it.
+ */
+ if(cpy_info->max_depth >= 0 && cpy_info->curr_depth >= cpy_info->max_depth)
+ *deleted = TRUE;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_pre_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_link_copy_file
*
* Purpose: Copies a message from _MESG to _DEST in file
@@ -478,7 +518,7 @@ done:
*/
static void *
H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_dst,
-hid_t UNUSED dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void UNUSED *udata)
+ hid_t UNUSED dxpl_id, H5O_copy_t UNUSED *cpy_info, void UNUSED *udata)
{
H5O_link_t *link_src = (H5O_link_t *) native_src;
H5O_link_t *link_dst = NULL;
@@ -489,6 +529,8 @@ hid_t UNUSED dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void
/* check args */
HDassert(link_src);
HDassert(file_dst);
+ HDassert(cpy_info);
+ HDassert(cpy_info->max_depth < 0 || cpy_info->curr_depth < cpy_info->max_depth);
/* Allocate space for the destination stab */
if(NULL == (link_dst = H5FL_MALLOC(H5O_link_t)))
@@ -543,10 +585,11 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
- hbool_t *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list)
+H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst,
+ hbool_t *modified, 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_src = (H5O_link_t *)mesg_src; /* Casting away const OK... -QAK */
+ H5O_link_t tmp_link_src;
H5O_link_t *link_dst = (H5O_link_t *)mesg_dst;
herr_t ret_value = SUCCEED; /* Return value */
@@ -559,7 +602,42 @@ H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_ol
HDassert(dst_oloc->file);
HDassert(link_dst);
HDassert(modified && *modified == FALSE);
- HDassert(map_list);
+ HDassert(cpy_info);
+ HDassert(cpy_info->max_depth < 0 || cpy_info->curr_depth < cpy_info->max_depth);
+
+ /* Expand soft link */
+ if(H5G_LINK_SOFT == link_src->type && cpy_info->expand_soft_link) {
+ H5G_stat_t statbuf; /* Information about object pointed to by soft link */
+ H5G_loc_t grp_loc; /* Group location for parent of soft link */
+ H5G_name_t grp_path; /* Path for parent of soft link */
+
+ /* Make a temporary copy, so that it will not change the info in the cache */
+ HDmemcpy(&tmp_link_src, link_src, sizeof(H5O_link_t));
+ link_src = &tmp_link_src;
+
+ /* Set up group location for soft link to start in */
+ H5G_name_reset(&grp_path);
+ grp_loc.path = &grp_path;
+ grp_loc.oloc = (H5O_loc_t *)parent_src_oloc; /* Casting away const OK... -QAK */
+
+ /* Check if the object pointed by the soft link exists in the source file */
+ /* (It would be more efficient to make a specialized traversal callback,
+ * but this is good enough for now... -QAK)
+ */
+ if(H5G_get_objinfo(&grp_loc, link_src->u.soft.name, TRUE, &statbuf, H5AC_ind_dxpl_id) >= 0) {
+ /* Convert temp. copy of source soft link to hard link */
+#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG
+ link_src->u.hard.addr = (((haddr_t)statbuf.objno[1]) << (8 * sizeof(long))) | (haddr_t)statbuf.objno[0];
+#else
+ link_src->u.hard.addr = statbuf.objno[0];
+#endif
+ link_src->type = H5G_LINK_HARD;
+
+ /* Convert destination link to hard link */
+ link_dst->type = H5G_LINK_HARD;
+ link_dst->u.soft.name = H5MM_xfree(link_dst->u.soft.name);
+ } /* end if */
+ } /* if ((H5G_CACHED_SLINK == src_ent->type)... */
/* Additional "deep copy" for each kind of link */
switch(link_src->type) {
@@ -571,7 +649,7 @@ H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_ol
/* Build temporary object location for source */
H5O_loc_reset(&src_oloc);
- src_oloc.file = file_src;
+ src_oloc.file = parent_src_oloc->file;
HDassert(H5F_addr_defined(link_src->u.hard.addr));
src_oloc.addr = link_src->u.hard.addr;
@@ -580,8 +658,7 @@ H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_ol
new_oloc.file = dst_oloc->file;
/* Copy the shared object from source to destination */
- /* (Increments link count on destination) */
- if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, cpy_option, map_list) < 0)
+ if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, cpy_info, TRUE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Update link information with new destination object's address */
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index ec453f7..cdcfe0f 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -24,7 +24,6 @@
/* Other private headers needed by this file */
#include "H5ACprivate.h" /* Metadata cache */
-#include "H5SLprivate.h" /* Skip lists */
/*
* Align messages on 8-byte boundaries because we would like to copy the
@@ -73,9 +72,9 @@ struct H5O_msg_class_t {
herr_t (*link)(H5F_t *, hid_t, const void *); /* Increment any links in file reference by this message */
herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*); /* Get shared information */
herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*); /* Set shared information */
- herr_t (*pre_copy_file)(H5F_t *, const H5O_msg_class_t *, void *, void *); /*"pre copy" action when copying native value to file */
- void *(*copy_file)(H5F_t *, void *, H5F_t *, hid_t, unsigned, H5SL_t *, void *); /*copy native value to file */
- herr_t (*post_copy_file)(H5F_t *, const void *, H5O_loc_t *, void *, hbool_t *, hid_t, unsigned, H5SL_t *); /*"post copy" action when copying native value to file */
+ herr_t (*pre_copy_file)(H5F_t *, const H5O_msg_class_t *, 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 *, hid_t, H5O_copy_t *, void *); /*copy native value to file */
+ herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, hbool_t *, hid_t, H5O_copy_t *); /*"post copy" action when copying native value to file */
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
};
diff --git a/src/H5Opline.c b/src/H5Opline.c
index d27cfb2..9658e07 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -37,9 +37,9 @@ static size_t H5O_pline_size (const H5F_t *f, const void *_mesg);
static herr_t H5O_pline_reset (void *_mesg);
static herr_t H5O_pline_free (void *_mesg);
static herr_t H5O_pline_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type,
- void *mesg_src, void *_udata);
+ void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
static herr_t H5O_pline_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg,
- FILE * stream, int indent, int fwidth);
+ FILE * stream, int indent, int fwidth);
/* This message derives from H5O message class */
const H5O_msg_class_t H5O_MSG_PLINE[1] = {{
@@ -441,7 +441,9 @@ H5O_pline_free (void *mesg)
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_pline_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type, void *mesg_src, void *_udata)
+H5O_pline_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t UNUSED *type,
+ void *mesg_src, hbool_t UNUSED *deleted, const H5O_copy_t UNUSED *cpy_info,
+ void *_udata)
{
H5O_pline_t *pline_src = (H5O_pline_t *)mesg_src; /* Source datatype */
H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index a0f2bbd..ee3f5da 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -36,6 +36,7 @@
/* Private headers needed by this file */
#include "H5Fprivate.h" /* File access */
+#include "H5SLprivate.h" /* Skip lists */
#include "H5Tprivate.h" /* Datatype functions */
#include "H5Zprivate.h" /* I/O pipeline filters */
@@ -65,6 +66,18 @@ typedef struct H5O_loc_t {
haddr_t addr; /* File address of object header */
} H5O_loc_t;
+/* Settings/flags for copying an object */
+typedef struct H5O_copy_t {
+ hbool_t copy_shallow; /* Flag to perform shallow hierarchy copy */
+ hbool_t expand_soft_link; /* Flag to expand soft links */
+ hbool_t expand_ext_link; /* Flag to expand external links */
+ hbool_t expand_obj_ref; /* Flag to expand object references */
+ hbool_t copy_without_attr; /* Flag to not copy attributes */
+ 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 */
+} H5O_copy_t;
+
/* Header message IDs */
#define H5O_NULL_ID 0x0000 /* Null Message. */
#define H5O_SDSPACE_ID 0x0001 /* Simple Dataspace Message. */
@@ -347,7 +360,7 @@ H5_DLL H5G_obj_t H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id);
H5_DLL herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
hid_t dxpl_id, unsigned cpy_option);
H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
- hid_t dxpl_id, unsigned cpy_option, struct H5SL_t *map_list);
+ hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth);
H5_DLL herr_t H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
int fwidth);
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index ccdb61c..dc5ea6f 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -43,9 +43,9 @@ static size_t H5O_shared_size (const H5F_t*, const void *_mesg);
static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
static herr_t H5O_shared_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type,
- void *mesg_src, void *_udata);
+ void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata);
static void *H5O_shared_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
+ H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
static herr_t H5O_shared_debug (H5F_t*, hid_t dxpl_id, const void*, FILE*, int, int);
/* This message derives from H5O message class */
@@ -429,7 +429,7 @@ done:
*/
static void *
H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
- hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void UNUSED *udata)
+ hid_t dxpl_id, H5O_copy_t *cpy_info, void UNUSED *udata)
{
H5O_shared_t *shared_src = (H5O_shared_t *)native_src;
H5O_shared_t *shared_dst = NULL;
@@ -440,7 +440,7 @@ H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
/* check args */
HDassert(shared_src);
HDassert(file_dst);
- HDassert(map_list);
+ HDassert(cpy_info);
/* Allocate space for the destination message */
if(NULL == (shared_dst = H5MM_malloc(sizeof(H5O_shared_t))))
@@ -451,7 +451,7 @@ H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t *file_dst,
shared_dst->oloc.file = file_dst;
/* Copy the shared object from source to destination */
- if(H5O_copy_header_map(&(shared_src->oloc), &(shared_dst->oloc), dxpl_id, cpy_option, map_list) < 0)
+ if(H5O_copy_header_map(&(shared_src->oloc), &(shared_dst->oloc), dxpl_id, cpy_info, FALSE) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
/* Set return value */
@@ -482,28 +482,30 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_shared_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, void *native_src, void *udata)
+H5O_shared_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type,
+ void *native_src, hbool_t *deleted, const H5O_copy_t *cpy_info,
+ void *udata)
{
H5O_shared_t *shared_src = (H5O_shared_t *)native_src;
void *mesg_native = NULL;
- hid_t dxpl_id = H5AC_dxpl_id;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_shared_pre_copy_file)
+ /* check args */
+ HDassert(file_src);
+ HDassert(type);
+
if(type->pre_copy_file) {
- if((mesg_native = H5O_read_real(&(shared_src->oloc), type, 0, NULL, dxpl_id)) == NULL)
+ /* Go get the actual shared message */
+ if((mesg_native = H5O_read_real(&(shared_src->oloc), type, 0, NULL, H5AC_dxpl_id)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to load object header")
/* Perform "pre copy" operation on messge */
- if((type->pre_copy_file)(file_src, type, mesg_native, udata) < 0)
+ if((type->pre_copy_file)(file_src, type, mesg_native, deleted, cpy_info, udata) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'pre copy' operation on message")
} /* end of if */
- /* check args */
- HDassert(file_src);
- HDassert(type);
-
done:
if(mesg_native)
H5O_free_real(type, mesg_native);
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 241bd94..7516afd 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -44,9 +44,9 @@ static size_t H5O_stab_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_stab_free(void *_mesg);
static herr_t H5O_stab_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static void *H5O_stab_copy_file(H5F_t *file_src, void *native_src,
- H5F_t *file_dst, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list, void *udata);
-static herr_t H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc,
- void *mesg_dst, hbool_t *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list);
+ H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata);
+static herr_t H5O_stab_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
+ void *mesg_dst, hbool_t *modified, 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);
@@ -312,7 +312,7 @@ done:
*/
static void *
H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst,
- hid_t dxpl_id, UNUSED unsigned cpy_option, H5SL_t UNUSED *map_list, void UNUSED *udata)
+ hid_t dxpl_id, H5O_copy_t UNUSED *cpy_info, void UNUSED *udata)
{
H5O_stab_t *stab_src = (H5O_stab_t *) native_src;
H5O_stab_t *stab_dst = NULL;
@@ -362,12 +362,13 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src, H5O_loc_t *dst_oloc,
-void *mesg_dst, hbool_t UNUSED *modified, hid_t dxpl_id, unsigned cpy_option, H5SL_t *map_list)
+H5O_stab_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, H5O_loc_t *dst_oloc,
+ void *mesg_dst, hbool_t UNUSED *modified, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
H5G_bt_it_ud5_t udata; /* B-tree user data */
const H5O_stab_t *stab_src = (const H5O_stab_t *)mesg_src;
H5O_stab_t *stab_dst = (H5O_stab_t *)mesg_dst;
+ H5F_t *file_src = parent_src_oloc->file;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_stab_post_copy_file)
@@ -378,14 +379,18 @@ void *mesg_dst, hbool_t UNUSED *modified, hid_t dxpl_id, unsigned cpy_option, H5
HDassert(H5F_addr_defined(dst_oloc->addr));
HDassert(dst_oloc->file);
HDassert(stab_dst);
- HDassert(map_list);
+ HDassert(cpy_info);
+
+ /* If we are performing a 'shallow hierarchy' copy, get out now */
+ if(cpy_info->max_depth >= 0 && cpy_info->curr_depth >= cpy_info->max_depth)
+ HGOTO_DONE(SUCCEED)
/* Set up B-tree iteration user data */
- udata.map_list = map_list;
+ udata.src_oloc = (H5O_loc_t *)parent_src_oloc; /* Casting away const OK - QAK */
udata.src_heap_addr = stab_src->heap_addr;
udata.dst_file = dst_oloc->file;
udata.dst_stab = stab_dst;
- udata.cpy_option = cpy_option;
+ udata.cpy_info = cpy_info;
/* Iterate over objects in group, copying them */
if((H5B_iterate(file_src, dxpl_id, H5B_SNODE, H5G_node_copy, stab_src->btree_addr, &udata)) < 0)