diff options
Diffstat (limited to 'src/H5Gent.c')
-rw-r--r-- | src/H5Gent.c | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/src/H5Gent.c b/src/H5Gent.c index a2e6159..cec788c 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -352,7 +352,8 @@ H5G_ent_reset(H5G_entry_t *ent) */ herr_t H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, const char *name, - const H5O_link_t *lnk, H5G_entry_t *ent) + const H5O_link_t *lnk, H5O_type_t obj_type, const void *crt_info, + H5G_entry_t *ent) { size_t name_offset; /* Offset of name in heap */ herr_t ret_value = SUCCEED; /* Return value */ @@ -373,13 +374,91 @@ H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, const char *name, */ name_offset = H5HL_insert(f, dxpl_id, heap, HDstrlen(name) + 1, name); if(0 == name_offset || (size_t)(-1) == name_offset) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert symbol name into heap") + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert symbol name into heap") ent->name_off = name_offset; /* Build correct information for symbol table entry based on link type */ switch(lnk->type) { case H5L_TYPE_HARD: - ent->type = H5G_NOTHING_CACHED; + if(obj_type == H5O_TYPE_GROUP) { + const H5G_obj_create_t *gcrt_info = (const H5G_obj_create_t *)crt_info; + + ent->type = gcrt_info->cache_type; + if(ent->type != H5G_NOTHING_CACHED) + ent->cache = gcrt_info->cache; +#ifndef NDEBUG + else { + /* Make sure there is no stab message in the target object + */ + H5O_loc_t targ_oloc; /* Location of link target */ + htri_t stab_exists; /* Whether the target symbol table exists */ + + /* Build target object location */ + if(H5O_loc_reset(&targ_oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize target location") + targ_oloc.file = f; + targ_oloc.addr = lnk->u.hard.addr; + + /* Check if a symbol table message exists */ + if((stab_exists = H5O_msg_exists(&targ_oloc, H5O_STAB_ID, + dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for STAB message") + + HDassert(!stab_exists); + } /* end else */ +#endif /* NDEBUG */ + } /* end if */ + else if(obj_type == H5O_TYPE_UNKNOWN){ + /* Try to retrieve symbol table information for caching */ + H5O_loc_t targ_oloc; /* Location of link target */ + H5O_t *oh; /* Link target object header */ + H5O_stab_t stab; /* Link target symbol table */ + htri_t stab_exists; /* Whether the target symbol table exists */ + + /* Build target object location */ + if(H5O_loc_reset(&targ_oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize target location") + targ_oloc.file = f; + targ_oloc.addr = lnk->u.hard.addr; + + /* Get the object header */ + if(NULL == (oh = H5O_protect(&targ_oloc, dxpl_id, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_CANTPROTECT, FAIL, "unable to protect target object header") + + /* Check if a symbol table message exists */ + if((stab_exists = H5O_msg_exists_oh(oh, H5O_STAB_ID)) < 0) { + if(H5O_unprotect(&targ_oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) + < 0) + HERROR(H5E_SYM, H5E_CANTUNPROTECT, "unable to release object header"); + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for STAB message") + } /* end if */ + + if(stab_exists) { + /* Read symbol table message */ + if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_STAB_ID, + &stab)) { + if(H5O_unprotect(&targ_oloc, dxpl_id, oh, + H5AC__NO_FLAGS_SET) < 0) + HERROR(H5E_SYM, H5E_CANTUNPROTECT, "unable to release object header"); + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read STAB message") + } /* end if */ + + /* Cache symbol table message */ + ent->type = H5G_CACHED_STAB; + ent->cache.stab.btree_addr = stab.btree_addr; + ent->cache.stab.heap_addr = stab.heap_addr; + } /* end if */ + else + /* No symbol table message, don't cache anything */ + ent->type = H5G_NOTHING_CACHED; + + if(H5O_unprotect(&targ_oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) + < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTUNPROTECT, FAIL, "unable to release object header") + } /* end else */ + else + ent->type = H5G_NOTHING_CACHED; + ent->header = lnk->u.hard.addr; break; |