summaryrefslogtreecommitdiffstats
path: root/src/H5Gnode.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/H5Gnode.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/H5Gnode.c')
-rw-r--r--src/H5Gnode.c92
1 files changed, 77 insertions, 15 deletions
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index dabb01c..c640a65 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -283,16 +283,23 @@ H5G_node_debug_key (FILE *stream, H5F_t *f, hid_t dxpl_id, int indent, int fwidt
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Heap offset:",
(unsigned)key->offset);
- HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:");
+ if(udata->heap_addr != 0)
+ {
+ HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:");
- if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name");
+ if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name");
- s = H5HL_offset_into(f, heap, key->offset);
- HDfprintf (stream, "%s\n", s);
+ s = H5HL_offset_into(f, heap, key->offset);
+ HDfprintf (stream, "%s\n", s);
- if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name");
+ if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name");
+ }
+ else
+ {
+ HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Cannot get name; heap address not specified\n");
+ }
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1242,7 +1249,10 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
if(cmp)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "not found")
- if(H5G_CACHED_SLINK == sn->entry[idx].type) {
+ switch(sn->entry[idx].type)
+ {
+ case H5G_CACHED_SLINK:
+ {
/* Set the type of the link removed */
*(udata->obj_type) = H5G_LINK;
@@ -1266,7 +1276,42 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].cache.slink.lval_offset, len);
H5E_clear_stack(NULL); /* no big deal */
- } else {
+ }
+ break;
+
+ case H5G_CACHED_ULINK:
+ {
+ size_t ud_data_size = 0; /* User link data size */
+ hbool_t ud_data_found; /* Indicate that the link user data was found */
+
+ /* Set the type of the link removed */
+ *(udata->obj_type) = H5G_UDLINK;
+
+ /* Remove the link user data from the heap */
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name")
+
+ s = H5HL_offset_into(f, heap, sn->entry[idx].cache.ulink.udata_offset);
+ if(s)
+ {
+ ud_data_found = 1;
+ ud_data_size = sn->entry[idx].cache.ulink.udata_size;
+ }
+ else
+ ud_data_found = 0;
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name")
+ heap = NULL; s = NULL;
+
+ if(ud_data_found)
+ H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].cache.ulink.udata_offset, ud_data_size);
+
+ H5E_clear_stack(NULL); /* no big deal */
+ }
+ break;
+
+ default:
+ {
H5O_loc_t tmp_oloc; /* Temporary object location */
/* Build temporary object location */
@@ -1283,7 +1328,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
if(H5O_link(&tmp_oloc, -1, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to decrement object link count")
} /* end if */
- } /* end else */
+ }
+ } /* end switch */
/* Remove the name from the local heap */
if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
@@ -1372,7 +1418,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
/* Reduce the link count for all entries in this node */
for(idx = 0; idx < sn->nsyms; idx++) {
- if(H5G_CACHED_SLINK != sn->entry[idx].type) {
+ if(!(H5G_CACHED_SLINK == sn->entry[idx].type ||
+ H5G_CACHED_ULINK == sn->entry[idx].type)) {
/* Decrement the reference count, if requested */
if(udata->adj_link) {
HDassert(H5F_addr_defined(sn->entry[idx].header));
@@ -1670,17 +1717,24 @@ H5G_node_type(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
loc_idx = udata->idx - udata->num_objs;
/* Check for a soft link */
- if(sn->entry[loc_idx].type == H5G_CACHED_SLINK)
+ switch(sn->entry[loc_idx].type)
+ {
+ case H5G_CACHED_SLINK:
udata->type = H5G_LINK;
- /* Must be a hard link */
- else {
+ break;
+ case H5G_CACHED_ULINK:
+ udata->type = H5G_UDLINK;
+ break;
+
+ default:
/* Build temporary object location */
tmp_oloc.file = f;
HDassert(H5F_addr_defined(sn->entry[loc_idx].header));
tmp_oloc.addr = sn->entry[loc_idx].header;
udata->type = H5O_obj_type(&tmp_oloc, dxpl_id);
- } /* end else */
+ break;
+ }
ret_value = H5B_ITER_STOP;
} else {
udata->num_objs += sn->nsyms;
@@ -1997,6 +2051,14 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
lnk.type = H5L_LINK_SOFT;
lnk.u.soft.name = H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset);
} /* else if */
+ else if(H5G_CACHED_ULINK == src_ent->type) {
+ /* user-defined link */
+
+ /* Construct link information for eventual insertion */
+ lnk.type = src_ent->cache.ulink.link_type;
+ lnk.u.ud.size = src_ent->cache.ulink.udata_size;
+ lnk.u.ud.udata = H5HL_offset_into(f, heap, src_ent->cache.ulink.udata_offset);
+ } /* else if */
else
HDassert(0 && "Unknown entry type");