summaryrefslogtreecommitdiffstats
path: root/src/H5Olink.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
commita1708eb023f2c8f8ac6c2c17bf1e598c8dff956e (patch)
tree34c87a3753b36c4c8d689d58bf456eaf261cd235 /src/H5Olink.c
parentbea1e576c5ef5500678f7ce913d835341b625e8f (diff)
downloadhdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.zip
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.gz
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.bz2
[svn-r11712] Purpose:
New feature Description: Check in baseline for compact group revisions, which radically revises the source code for managing groups and object headers. WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! This initiates the "unstable" phase of the 1.7.x branch, leading up to the 1.8.0 release. Please test this code, but do _NOT_ keep files created with it - the format will change again before the release and you will not be able to read your old files!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! Solution: There's too many changes to really describe them all, but some of them include: - Stop abusing the H5G_entry_t structure and split it into two separate structures for non-symbol table node use within the library: H5O_loc_t for object locations in a file and H5G_name_t to store the path to an opened object. H5G_entry_t is now only used for storing symbol table entries on disk. - Retire H5G_namei() in favor of a more general mechanism for traversing group paths and issuing callbacks on objects located. This gets us out of the business of hacking H5G_namei() for new features, generally. - Revised H5O* routines to take a H5O_loc_t instead of H5G_entry_t - Lots more... Platforms tested: h5committested and maybe another dozen configurations.... :-)
Diffstat (limited to 'src/H5Olink.c')
-rw-r--r--src/H5Olink.c672
1 files changed, 672 insertions, 0 deletions
diff --git a/src/H5Olink.c b/src/H5Olink.c
new file mode 100644
index 0000000..2284ecb
--- /dev/null
+++ b/src/H5Olink.c
@@ -0,0 +1,672 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Olink.c
+ * Aug 29 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Link messages.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define H5O_PACKAGE /*suppress error about including H5Opkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Opkg.h" /* Object headers */
+
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_link_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
+static herr_t H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg);
+static void *H5O_link_copy(const void *_mesg, void *_dest, unsigned update_flags);
+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 void *H5O_link_copy_file(H5F_t *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, 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, H5SL_t *map_list);
+static herr_t H5O_link_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
+ FILE * stream, int indent, int fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_LINK[1] = {{
+ H5O_LINK_ID, /*message id number */
+ "link", /*message name for debugging */
+ sizeof(H5O_link_t), /*native message size */
+ H5O_link_decode, /*decode message */
+ H5O_link_encode, /*encode message */
+ H5O_link_copy, /*copy the native value */
+ H5O_link_size, /*size of symbol table entry */
+ H5O_link_reset, /* reset method */
+ H5O_link_free, /* free method */
+ H5O_link_delete, /* file delete method */
+ NULL, /* link method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ 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 */
+}};
+
+/* Current version of link information */
+#define H5O_LINK_VERSION 1
+
+/* Declare a free list to manage the H5O_link_t struct */
+H5FL_DEFINE_STATIC(H5O_link_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_decode
+ *
+ * Purpose: Decode a message and return a pointer to
+ * a newly allocated one.
+ *
+ * Return: Success: Ptr to new message in native order.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
+{
+ H5O_link_t *lnk = NULL; /* Pointer to link message */
+ uint16_t len; /* Length of a string in the message */
+ uint32_t tmp_time; /* Temporary copy of the time */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_decode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+
+ /* decode */
+ if(*p++ != H5O_LINK_VERSION)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
+
+ /* Allocate space for message */
+ if(NULL == (lnk = H5FL_CALLOC(H5O_link_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Get the type of the link */
+ lnk->type = *p++;
+ if(lnk->type < H5G_LINK_HARD || lnk->type > H5G_LINK_SOFT)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type")
+
+ /* Get the link creation time from the file */
+ UINT32DECODE(p, tmp_time)
+ lnk->ctime = (time_t)tmp_time;
+
+ /* Get the link name's character set */
+ lnk->cset = (H5T_cset_t)*p++;
+ if(lnk->cset < H5T_CSET_ASCII || lnk->cset > H5T_CSET_UTF8)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad cset type")
+
+ /* Get the link's name */
+ UINT16DECODE(p, len)
+ if(len == 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid name length")
+ if(NULL == (lnk->name = H5MM_malloc((size_t)len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(lnk->name, p, len);
+ lnk->name[len] = '\0';
+ p += len;
+
+ /* Get the appropriate information for each type of link */
+ switch(lnk->type) {
+ case H5G_LINK_HARD:
+ /* Get the address of the object the link points to */
+ H5F_addr_decode(f, &p, &(lnk->u.hard.addr));
+ break;
+
+ case H5G_LINK_SOFT:
+ /* Get the link value */
+ UINT16DECODE(p, len)
+ if(len == 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid link length")
+ if(NULL == (lnk->u.soft.name = H5MM_malloc((size_t)len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(lnk->u.soft.name, p, len);
+ lnk->u.soft.name[len] = '\0';
+ p += len;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type")
+ break;
+ } /* end switch */
+
+ /* Set return value */
+ ret_value=lnk;
+
+done:
+ if(ret_value == NULL)
+ if(lnk != NULL) {
+ if(lnk->name != NULL)
+ H5MM_xfree(lnk->name);
+ if(lnk->type == H5G_LINK_SOFT && lnk->u.soft.name != NULL)
+ H5MM_xfree(lnk->u.soft.name);
+ H5FL_FREE(H5O_link_t, lnk);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_encode
+ *
+ * Purpose: Encodes a link message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *) _mesg;
+ uint16_t len; /* Length of a string in the message */
+ uint32_t tmp_time; /* Temporary copy of the time */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_encode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+ HDassert(lnk);
+
+ /* encode */
+ *p++ = H5O_LINK_VERSION;
+
+ /* Store the type of the link */
+ *p++ = lnk->type;
+
+ /* Store the link creation time from the file */
+ tmp_time = lnk->ctime;
+ UINT32ENCODE(p, tmp_time)
+
+ /* Store the link name's character set */
+ *p++ = (uint8_t)lnk->cset;
+
+ /* Store the link's name */
+ len = (uint16_t)HDstrlen(lnk->name);
+ HDassert(len > 0);
+ UINT16ENCODE(p, len)
+ HDmemcpy(p, lnk->name, len);
+ p += len;
+
+ /* Store the appropriate information for each type of link */
+ switch(lnk->type) {
+ case H5G_LINK_HARD:
+ /* Store the address of the object the link points to */
+ H5F_addr_encode(f, &p, lnk->u.hard.addr);
+ break;
+
+ case H5G_LINK_SOFT:
+ /* Store the link value */
+ len = (uint16_t)HDstrlen(lnk->u.soft.name);
+ HDassert(len > 0);
+ UINT16ENCODE(p, len)
+ HDmemcpy(p, lnk->u.soft.name, len);
+ p += len;
+ break;
+
+ default:
+ HDassert((lnk->type == H5G_LINK_HARD) || (lnk->type == H5G_LINK_SOFT));
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_link_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *) _mesg;
+ H5O_link_t *dest = (H5O_link_t *) _dest;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_copy)
+
+ /* check args */
+ HDassert(lnk);
+ if(!dest && NULL == (dest = H5FL_MALLOC(H5O_link_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* copy */
+ *dest = *lnk;
+ HDassert(lnk->name);
+ dest->name = H5MM_xstrdup(lnk->name);
+ if(lnk->type == H5G_LINK_SOFT)
+ dest->u.soft.name = H5MM_xstrdup(lnk->u.soft.name);
+
+ /* Set return value */
+ ret_value=dest;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting
+ * the message type or size fields, but only the data fields.
+ * This function doesn't take into account alignment.
+ *
+ * Return: Success: Message data size in bytes without alignment.
+ *
+ * Failure: zero
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_link_size(const H5F_t *f, const void *_mesg)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg;
+ size_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_size)
+
+ /* Set return value */
+ ret_value = 1 + /* Version */
+ 1 + /* Link type */
+ 4 + /* Creation time */
+ 1 + /* Character set */
+ 2 + /* Name length */
+ HDstrlen(lnk->name); /* Name */
+
+ /* Add the appropriate length for each type of link */
+ switch(lnk->type) {
+ case H5G_LINK_HARD:
+ ret_value += H5F_SIZEOF_ADDR(f);
+ break;
+
+ case H5G_LINK_SOFT:
+ ret_value += 2 + /* Link value length */
+ HDstrlen(lnk->u.soft.name); /* Link value */
+ break;
+
+ default:
+ HDassert((lnk->type == H5G_LINK_HARD) || (lnk->type == H5G_LINK_SOFT));
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_reset
+ *
+ * Purpose: Frees resources within a message, but doesn't free
+ * the message itself.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 29, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_reset(void *_mesg)
+{
+ H5O_link_t *lnk = (H5O_link_t *)_mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_reset)
+
+ if(lnk) {
+ /* Free information for link (but don't free link pointer) */
+ if(lnk->type == H5G_LINK_SOFT)
+ lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name);
+ lnk->name = H5MM_xfree(lnk->name);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_free
+ *
+ * Purpose: Free's the message contents and the message itself
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 29, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_free(void *_mesg)
+{
+ H5O_link_t *lnk = (H5O_link_t *)_mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_free)
+
+ HDassert(lnk);
+
+ /* Free information for link */
+ if(lnk->type == H5G_LINK_SOFT)
+ lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name);
+ lnk->name = H5MM_xfree(lnk->name);
+ H5FL_FREE(H5O_link_t, lnk);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_delete
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 29, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_delete)
+
+ /* check args */
+ HDassert(f);
+ HDassert(lnk);
+
+ /* Decrement reference count to the object, for hard links */
+ if(lnk->type == H5G_LINK_HARD) {
+ H5O_loc_t oloc;
+
+ /* Construct object location for object, in order to decrement it's ref count */
+ H5O_loc_reset(&oloc);
+ oloc.file = f;
+ HDassert(H5F_addr_defined(lnk->u.hard.addr));
+ oloc.addr = lnk->u.hard.addr;
+
+ /* Decrement the ref count for the object, if requested */
+ if(adj_link)
+ if(H5O_link(&oloc, -1, dxpl_id)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to decrement object link count")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * November 7, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src,
+ H5F_t UNUSED *file_dst, hid_t UNUSED dxpl_id, H5SL_t UNUSED *map_list, void UNUSED *udata)
+{
+ H5O_link_t *link_src = (H5O_link_t *) native_src;
+ H5O_link_t *link_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_copy_file)
+
+ /* check args */
+ HDassert(link_src);
+ HDassert(file_dst);
+
+ /* Allocate space for the destination stab */
+ if(NULL == (link_dst = H5FL_MALLOC(H5O_link_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy top-level information */
+ *link_dst = *link_src;
+
+ /* Deep copy the link's name */
+ if(NULL == (link_dst->name = H5MM_xstrdup(link_src->name)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* "Deep copy" other information for each kind of link */
+ switch(link_src->type) {
+ case H5G_LINK_HARD:
+ /* Set link's address undefined here, will be fixed up in "post copy" callback */
+ link_dst->u.hard.addr = HADDR_UNDEF;
+ break;
+
+ case H5G_LINK_SOFT:
+ /* Copy the soft link's value */
+ if(NULL == (link_dst->u.soft.name = H5MM_xstrdup(link_src->u.soft.name)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "unrecognized link type")
+ } /* end switch */
+
+ /* Set return value */
+ ret_value = link_dst;
+
+done:
+ if(!ret_value)
+ if(link_dst)
+ H5FL_FREE(H5O_link_t, link_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_link_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_post_copy_file
+ *
+ * Purpose: Finish copying a message from between files
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * November 7, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+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, H5SL_t *map_list)
+{
+ const H5O_link_t *link_src = (const H5O_link_t *)mesg_src;
+ H5O_link_t *link_dst = (H5O_link_t *)mesg_dst;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_post_copy_file)
+
+ /* check args */
+ HDassert(link_src);
+ HDassert(dst_oloc);
+ HDassert(H5F_addr_defined(dst_oloc->addr));
+ HDassert(dst_oloc->file);
+ HDassert(link_dst);
+ HDassert(modified && *modified == FALSE);
+ HDassert(map_list);
+
+ /* Additional "deep copy" for each kind of link */
+ switch(link_src->type) {
+ case H5G_LINK_HARD:
+ /* Copy the object pointed to */
+ {
+ H5O_loc_t src_oloc; /* Temporary object location for source object */
+ H5O_loc_t new_oloc; /* Temporary object location for source object */
+
+ /* Build temporary object location for source */
+ H5O_loc_reset(&src_oloc);
+ src_oloc.file = file_src;
+ HDassert(H5F_addr_defined(link_src->u.hard.addr));
+ src_oloc.addr = link_src->u.hard.addr;
+
+ /* Build temporary object location for destination */
+ H5O_loc_reset(&new_oloc);
+ 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, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* Update link information with new destination object's address */
+ link_dst->u.hard.addr = new_oloc.addr;
+
+ /* Indicate that the destination message was modified */
+ *modified = TRUE;
+ } /* end case */
+ break;
+
+ case H5G_LINK_SOFT:
+ HGOTO_DONE(SUCCEED)
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_link_post_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_debug
+ *
+ * Purpose: Prints debugging info for a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream,
+ int indent, int fwidth)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *) _mesg;
+ struct tm *tm;
+ char buf[128];
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_debug)
+
+ /* check args */
+ HDassert(f);
+ HDassert(lnk);
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Type:", (lnk->type == H5G_LINK_HARD ? "Hard" :
+ (lnk->type == H5G_LINK_SOFT ? "Soft" : "Unknown")));
+
+ tm = HDlocaltime(&(lnk->ctime));
+ HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Creation Time:", buf);
+
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Name Character Set:", (lnk->cset == H5T_CSET_ASCII ?
+ "ASCII" : (lnk->cset == H5T_CSET_UTF8 ? "UTF-8" : "Unknown")));
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Name:", lnk->name);
+
+ switch(lnk->type) {
+ case H5G_LINK_HARD:
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Object address:", lnk->u.hard.addr);
+ break;
+
+ case H5G_LINK_SOFT:
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Value:", lnk->u.soft.name);
+ break;
+
+ default:
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_debug() */
+