summaryrefslogtreecommitdiffstats
path: root/src/H5Glink.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/H5Glink.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/H5Glink.c')
-rw-r--r--src/H5Glink.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/src/H5Glink.c b/src/H5Glink.c
index bf23058..1139e7c 100644
--- a/src/H5Glink.c
+++ b/src/H5Glink.c
@@ -294,7 +294,8 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
HDassert(name);
/* Create link message from object entry */
- HDassert(ent->type == H5G_NOTHING_CACHED || ent->type == H5G_CACHED_SLINK);
+ HDassert(ent->type == H5G_NOTHING_CACHED || ent->type == H5G_CACHED_SLINK
+ || ent->type == H5G_CACHED_ULINK);
/* XXX: Set character set & creation time for real? */
lnk->cset = H5F_CRT_DEFAULT_CSET;
lnk->ctime = 0;
@@ -302,7 +303,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
HDassert(lnk->name);
switch(ent->type) {
case H5G_NOTHING_CACHED:
- lnk->type = H5G_LINK_HARD;
+ lnk->type = H5L_LINK_HARD;
lnk->u.hard.addr = ent->header;
break;
@@ -310,7 +311,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
{
const char *s; /* Pointer to link value in heap */
- lnk->type = H5G_LINK_SOFT;
+ lnk->type = H5L_LINK_SOFT;
s = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset);
HDassert(s);
@@ -321,6 +322,25 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
}
break;
+ case H5G_CACHED_ULINK:
+ {
+ const char *s; /* Pointer to link name in heap */
+
+ /* Copy link type and udata size from entry info */
+ lnk->type = ent->cache.ulink.link_type;
+ lnk->u.ud.size = ent->cache.ulink.udata_size;
+
+ /* Get pointer to udata in heap */
+ s = H5HL_offset_into(ent->file, heap, ent->cache.ulink.udata_offset);
+ HDassert(s);
+
+ /* Read udata from heap */
+ if(NULL== (lnk->u.ud.udata = H5MM_malloc(lnk->u.ud.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for user link data")
+ HDmemcpy(lnk->u.ud.udata, s, lnk->u.ud.size);
+ }
+ break;
+
default:
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
} /* end switch */
@@ -454,9 +474,11 @@ H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound")
/* Determine type of object */
- if(ltable.lnks[idx].type == H5G_LINK_SOFT)
+ if(ltable.lnks[idx].type == H5L_LINK_SOFT)
ret_value = H5G_LINK;
- else {
+ else if(ltable.lnks[idx].type >= H5L_LINK_UD_MIN)
+ ret_value = H5G_UDLINK;
+ else if(ltable.lnks[idx].type == H5L_LINK_HARD){
H5O_loc_t tmp_oloc; /* Temporary object location */
/* Build temporary object location */
@@ -466,7 +488,9 @@ H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
/* Get the type of the object */
if((ret_value = H5O_obj_type(&tmp_oloc, dxpl_id)) == H5G_UNKNOWN)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "can't determine object type")
- } /* end else */
+ } else{
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "unknown link type")
+ }/* end else */
done:
/* Release link table */
@@ -501,7 +525,7 @@ H5G_link_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
H5G_link_ud2_t *udata = (H5G_link_ud2_t *)_udata; /* 'User data' passed in */
herr_t ret_value = H5O_ITER_CONT; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_link_remove_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5G_link_remove_cb)
/* check arguments */
HDassert(lnk);
@@ -509,20 +533,32 @@ H5G_link_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
/* If we've found the right link, get the object type */
if(HDstrcmp(lnk->name, udata->name) == 0) {
- if(lnk->type == H5G_LINK_SOFT)
- *(udata->obj_type) = H5G_LINK;
- else {
- H5O_loc_t tmp_oloc; /* Temporary object location */
+ switch(lnk->type)
+ {
+ case H5L_LINK_HARD:
+ {
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+
+ /* Build temporary object location */
+ tmp_oloc.file = udata->file;
+ tmp_oloc.addr = lnk->u.hard.addr;
+
+ /* Get the type of the object */
+ /* Note: no way to check for error :-( */
+ *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id);
+ }
+ break;
- /* Build temporary object location */
- tmp_oloc.file = udata->file;
- tmp_oloc.addr = lnk->u.hard.addr;
+ case H5L_LINK_SOFT:
+ *(udata->obj_type) = H5G_LINK;
+ break;
- /* Get the type of the object */
- /* Note: no way to check for error :-( */
- *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id);
- } /* end else */
+ default: /* User-defined link */
+ if(lnk->type < H5L_LINK_UD_MIN)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown link type");
+ *(udata->obj_type) = H5G_UDLINK;
+ }
/* Stop the iteration, we found the correct link */
HGOTO_DONE(H5O_ITER_STOP)
} /* end if */