summaryrefslogtreecommitdiffstats
path: root/src/H5Olink.c
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2006-08-02 23:41:53 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2006-08-02 23:41:53 (GMT)
commit3e755623cb24eb37c19fa645d74dc46948318253 (patch)
tree66e0a3807f37d50a8d6e5f3469864c604cd837c6 /src/H5Olink.c
parent71a4d0e9c48c4e02e5384cd3f6e38a2a530e9d22 (diff)
downloadhdf5-3e755623cb24eb37c19fa645d74dc46948318253.zip
hdf5-3e755623cb24eb37c19fa645d74dc46948318253.tar.gz
hdf5-3e755623cb24eb37c19fa645d74dc46948318253.tar.bz2
[svn-r12528] Added User-Defined links to the library.
Users can create external links using H5L_create_external(). These links point to an object in another HDF5 file. Users can alter the behavior of external links or create new kinds of links by registering callbacks using the H5L interface. Added tests, tools support, etc. Also a number of other, minor changes have been made (some restructuring of the H5L interface, for instance). Additional documentation and examples are forthcoming.
Diffstat (limited to 'src/H5Olink.c')
-rw-r--r--src/H5Olink.c81
1 files changed, 71 insertions, 10 deletions
diff --git a/src/H5Olink.c b/src/H5Olink.c
index 00a2b92..53fa99e 100644
--- a/src/H5Olink.c
+++ b/src/H5Olink.c
@@ -124,7 +124,7 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
/* Get the type of the link */
lnk->type = *p++;
- if(lnk->type < H5L_LINK_HARD || lnk->type > H5L_LINK_SOFT)
+ if(lnk->type < H5L_LINK_HARD || lnk->type > H5L_LINK_MAX)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type")
/* Get the link creation time from the file */
@@ -165,9 +165,21 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
p += len;
break;
+ /* User-defined linkes */
default:
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type")
- break;
+ if(lnk->type < H5L_LINK_UD_MIN || lnk->type > H5L_LINK_MAX)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type")
+
+ /* A UD link. Get the user-supplied data */
+ UINT16DECODE(p, len)
+ lnk->u.ud.size = len;
+ if(len > 0)
+ {
+ if(NULL == (lnk->u.ud.udata = H5MM_malloc((size_t)len)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(lnk->u.ud.udata, p, len);
+ p += len;
+ }
} /* end switch */
/* Set return value */
@@ -252,8 +264,18 @@ H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg)
p += len;
break;
+ /* User-defined links */
default:
- HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT));
+ HDassert(lnk->type >= H5L_LINK_UD_MIN && lnk->type <= H5L_LINK_MAX);
+
+ /* Store the user-supplied data, however long it is */
+ len = (uint16_t)lnk->u.ud.size;
+ UINT16ENCODE(p, len)
+ if(len > 0)
+ {
+ HDmemcpy(p, lnk->u.ud.udata, len);
+ p+=len;
+ }
break;
} /* end switch */
@@ -300,6 +322,14 @@ H5O_link_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags)
dest->name = H5MM_xstrdup(lnk->name);
if(lnk->type == H5L_LINK_SOFT)
dest->u.soft.name = H5MM_xstrdup(lnk->u.soft.name);
+ else if(lnk->type >= H5L_LINK_UD_MIN) {
+ if(lnk->u.ud.size != 0)
+ {
+ if(NULL == (dest->u.ud.udata = H5MM_malloc(lnk->u.ud.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(dest->u.ud.udata, lnk->u.ud.udata, lnk->u.ud.size);
+ }
+ }/* end if */
/* Set return value */
ret_value=dest;
@@ -354,8 +384,10 @@ H5O_link_size(const H5F_t *f, const void *_mesg)
HDstrlen(lnk->u.soft.name); /* Link value */
break;
- default:
- HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT));
+ default: /* Default is user-defined link type */
+ HDassert(lnk->type >= H5L_LINK_UD_MIN);
+ ret_value += 2 + /* User-defined data size */
+ lnk->u.ud.size; /* User-defined data */
break;
} /* end switch */
@@ -387,6 +419,12 @@ H5O_link_reset(void *_mesg)
/* Free information for link (but don't free link pointer) */
if(lnk->type == H5L_LINK_SOFT)
lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name);
+ else if (lnk->type >= H5L_LINK_UD_MIN) {
+ if(lnk->u.ud.size > 0)
+ {
+ lnk->u.ud.udata = H5MM_xfree(lnk->u.ud.udata);
+ }
+ } /* end if */
lnk->name = H5MM_xfree(lnk->name);
} /* end if */
@@ -561,6 +599,17 @@ H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_
break;
default:
+ if(link_src->type >= H5L_LINK_UD_MIN)
+ {
+ /* Copy the user-defined link's user data */
+ if(link_src->u.ud.size != 0)
+ {
+ if(NULL == (link_dst->u.ud.udata = H5MM_malloc(link_src->u.ud.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(link_dst->u.ud.udata, link_src->u.ud.udata, link_src->u.ud.size);
+ }
+ }
+ else
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "unrecognized link type")
} /* end switch */
@@ -610,7 +659,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src,
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) {
+ if(H5L_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 */
@@ -635,10 +684,10 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src,
#else
link_src->u.hard.addr = statbuf.objno[0];
#endif
- link_src->type = H5G_LINK_HARD;
+ link_src->type = H5L_LINK_HARD;
/* Convert destination link to hard link */
- link_dst->type = H5G_LINK_HARD;
+ link_dst->type = H5L_LINK_HARD;
link_dst->u.soft.name = H5MM_xfree(link_dst->u.soft.name);
} /* end if */
} /* if ((H5G_CACHED_SLINK == src_ent->type)... */
@@ -674,6 +723,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src,
break;
case H5L_LINK_SOFT:
+ case H5L_LINK_EXTERNAL:
HGOTO_DONE(SUCCEED)
break;
@@ -720,7 +770,9 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE *
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Link Type:", (lnk->type == H5L_LINK_HARD ? "Hard" :
- (lnk->type == H5L_LINK_SOFT ? "Soft" : "Unknown")));
+ (lnk->type == H5L_LINK_SOFT ? "Soft" :
+ (lnk->type == H5L_LINK_EXTERNAL ? "External" :
+ (lnk->type >= H5L_LINK_UD_MIN ? "User-defined" : "Unknown")))));
tm = HDlocaltime(&(lnk->ctime));
HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
@@ -744,6 +796,15 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE *
"Link Value:", lnk->u.soft.name);
break;
+ case H5L_LINK_EXTERNAL:
+ {
+ char * objname = (char *) lnk->u.ud.udata + (HDstrlen(lnk->u.ud.udata) + 1);
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link File Name:", lnk->u.ud.udata);
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Object Name:", objname);
+ }
+
default:
break;
} /* end switch */