/*------------------------------------------------------------------------- * Function: H5G__ent_to_link * * Purpose: Convert a symbol table entry to a link * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Sep 16 2006 * *------------------------------------------------------------------------- */ herr_t H5G__ent_to_link(H5O_link_t *lnk, const H5HL_t *heap, const H5G_entry_t *ent, const char *name) { FUNC_ENTER_PACKAGE_NOERR /* check arguments */ HDassert(lnk); HDassert(heap); HDassert(ent); HDassert(name); /* Set (default) common info for link */ lnk->cset = H5F_DEFAULT_CSET; lnk->corder = 0; lnk->corder_valid = FALSE; /* Creation order not valid for this link */ lnk->name = H5MM_xstrdup(name); HDassert(lnk->name); /* Object is a symbolic or hard link */ if(ent->type == H5G_CACHED_SLINK) { const char *s; /* Pointer to link value */ s = (const char *)H5HL_offset_into(heap, ent->cache.slink.lval_offset); HDassert(s); /* Copy the link value */ lnk->u.soft.name = H5MM_xstrdup(s); /* Set link type */ lnk->type = H5L_TYPE_SOFT; } /* end if */ else { /* Set address of object */ lnk->u.hard.addr = ent->header; /* Set link type */ lnk->type = H5L_TYPE_HARD; } /* end else */ FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G__ent_to_link() */
/*------------------------------------------------------------------------- * Function: H5G__ent_to_link * * Purpose: Convert a symbol table entry to a link * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Sep 16 2006 * *------------------------------------------------------------------------- */ herr_t H5G__ent_to_link(H5O_link_t *lnk, const H5HL_t *heap, const H5G_entry_t *ent, const char *name) { hbool_t dup_soft = FALSE; /* xstrdup the symbolic link name or not */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* check arguments */ HDassert(lnk); HDassert(heap); HDassert(ent); HDassert(name); /* Set (default) common info for link */ lnk->cset = H5F_DEFAULT_CSET; lnk->corder = 0; lnk->corder_valid = FALSE; /* Creation order not valid for this link */ if((lnk->name = H5MM_xstrdup(name)) == NULL) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to duplicate link name") /* Object is a symbolic or hard link */ if(ent->type == H5G_CACHED_SLINK) { const char *s; /* Pointer to link value */ if((s = (const char *)H5HL_offset_into(heap, ent->cache.slink.lval_offset)) == NULL) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get symbolic link name") /* Copy the link value */ if((lnk->u.soft.name = H5MM_xstrdup(s)) == NULL) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to duplicate symbolic link name") dup_soft = TRUE; /* Set link type */ lnk->type = H5L_TYPE_SOFT; } /* end if */ else {
/*------------------------------------------------------------------------- * Function: H5G_traverse_slink * * Purpose: Traverses symbolic link. The link head appears in the group * whose entry is GRP_ENT and the link head entry is OBJ_ENT. * * Return: Success: Non-negative, OBJ_ENT will contain information * about the object to which the link points and * GRP_ENT will contain the information about * the group in which the link tail appears. * * Failure: Negative * * Programmer: Robb Matzke * Friday, April 10, 1998 * * Modifications: * * Pedro Vicente, <*****@*****.**> 22 Aug 2002 * Added `id to name' support. * *------------------------------------------------------------------------- */ static herr_t H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/, H5G_entry_t *obj_ent/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id) { H5O_stab_t stab_mesg; /*info about local heap */ const char *clv = NULL; /*cached link value */ char *linkval = NULL; /*the copied link value */ H5G_entry_t tmp_grp_ent; /* Temporary copy of group entry */ H5RS_str_t *tmp_full_path_r = NULL, *tmp_user_path_r = NULL; /* Temporary pointer to object's user path & canonical path */ const H5HL_t *heap; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink); /* Portably initialize the temporary group entry */ H5G_ent_reset(&tmp_grp_ent); /* Get the link value */ if (NULL==H5O_read (grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address"); if (NULL == (heap = H5HL_protect(grp_ent->file, dxpl_id, stab_mesg.heap_addr))) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") clv = H5HL_offset_into(grp_ent->file, heap, obj_ent->cache.slink.lval_offset); linkval = H5MM_xstrdup (clv); assert(linkval); if (H5HL_unprotect(grp_ent->file, dxpl_id, heap, stab_mesg.heap_addr) < 0) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") /* Hold the entry's name (& old_name) to restore later */ tmp_full_path_r = obj_ent->full_path_r; obj_ent->full_path_r = NULL; tmp_user_path_r = obj_ent->user_path_r; obj_ent->user_path_r = NULL; /* Free the names for the group entry */ H5G_name_free(grp_ent); /* Clone the group entry, so we can track the names properly */ H5G_ent_copy(&tmp_grp_ent,grp_ent,H5_COPY_DEEP); /* Traverse the link */ if (H5G_namei (&tmp_grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, nlinks, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link"); /* Free the entry's names, we will use the original name for the object */ H5G_name_free(obj_ent); /* Restore previous name for object */ obj_ent->full_path_r = tmp_full_path_r; tmp_full_path_r = NULL; obj_ent->user_path_r = tmp_user_path_r; tmp_user_path_r = NULL; done: /* Error cleanup */ if(tmp_full_path_r) H5RS_decr(tmp_full_path_r); if(tmp_user_path_r) H5RS_decr(tmp_user_path_r); /* Release cloned copy of group entry */ H5G_name_free(&tmp_grp_ent); H5MM_xfree (linkval); FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_efl_decode * * Purpose: Decode an external file list message and return a pointer to * the message (and some other data). * * Return: Success: Ptr to a new message struct. * * Failure: NULL * * Programmer: Robb Matzke * Tuesday, November 25, 1997 * *------------------------------------------------------------------------- */ static void * H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p) { H5O_efl_t *mesg = NULL; int version; const char *s = NULL; H5HL_t *heap; size_t u; /* Local index variable */ void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_efl_decode) /* Check args */ HDassert(f); HDassert(p); if(NULL == (mesg = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Version */ version = *p++; if(version != H5O_EFL_VERSION) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for external file list message") /* Reserved */ p += 3; /* Number of slots */ UINT16DECODE(p, mesg->nalloc); assert(mesg->nalloc>0); UINT16DECODE(p, mesg->nused); assert(mesg->nused <= mesg->nalloc); /* Heap address */ H5F_addr_decode(f, &p, &(mesg->heap_addr)); #ifndef NDEBUG HDassert(H5F_addr_defined(mesg->heap_addr)); if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC_READ))) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value") s = (const char *)H5HL_offset_into(f, heap, 0); HDassert(s && !*s); if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value") heap = NULL; #endif /* Decode the file list */ mesg->slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t)); if(NULL == mesg->slot) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC_READ))) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value") for(u = 0; u < mesg->nused; u++) { /* Name */ H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset); s = (const char *)H5HL_offset_into(f, heap, mesg->slot[u].name_offset); HDassert(s && *s); mesg->slot[u].name = H5MM_xstrdup (s); HDassert(mesg->slot[u].name); /* File offset */ H5F_DECODE_LENGTH (f, p, mesg->slot[u].offset); /* Size */ H5F_DECODE_LENGTH (f, p, mesg->slot[u].size); HDassert(mesg->slot[u].size > 0); } /* end for */ if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value") heap = NULL; /* Set return value */ ret_value = mesg; done: if(ret_value == NULL) if(mesg != NULL) H5MM_xfree(mesg); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_efl_decode() */
/*------------------------------------------------------------------------- * Function: main * * Purpose: Create a file, create a local heap, write data into the local * heap, close the file, open the file, read data out of the * local heap, close the file. * * Return: Success: zero * * Failure: non-zero * * Programmer: Robb Matzke * Tuesday, November 24, 1998 * * Modifications: * *------------------------------------------------------------------------- */ int main(void) { hid_t fapl=H5P_DEFAULT; /*file access properties */ hid_t file=-1; /*hdf5 file */ H5F_t *f=NULL; /*hdf5 file pointer */ char filename[1024]; /*file name */ haddr_t heap_addr; /*local heap address */ H5HL_t *heap = NULL; /*local heap */ size_t obj[NOBJS]; /*offsets within the heap */ int i, j; /*miscellaneous counters */ char buf[1024]; /*the value to store */ const char *s; /*value to read */ /* Reset library */ h5_reset(); fapl = h5_fileaccess(); /* * Test writing to the heap... */ TESTING("local heap write"); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) goto error; if(NULL == (f = H5I_object(file))) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } if(H5HL_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)0, &heap_addr/*out*/) < 0) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } if (NULL == (heap = H5HL_protect(f, H5P_DATASET_XFER_DEFAULT, heap_addr, H5AC_WRITE))) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } for(i = 0; i < NOBJS; i++) { sprintf(buf, "%03d-", i); for (j=4; j<i; j++) buf[j] = '0' + j%10; if (j>4) buf[j] = '\0'; if ((size_t)(-1)==(obj[i]=H5HL_insert(f, H5P_DATASET_XFER_DEFAULT, heap, strlen(buf)+1, buf))) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } } if (H5HL_unprotect(f, H5P_DATASET_XFER_DEFAULT, heap, heap_addr) < 0) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } if (H5Fclose(file)<0) goto error; PASSED(); /* * Test reading from the heap... */ TESTING("local heap read"); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if ((file=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) goto error; if (NULL==(f=H5I_object(file))) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } for (i=0; i<NOBJS; i++) { sprintf(buf, "%03d-", i); for (j=4; j<i; j++) buf[j] = '0' + j%10; if (j>4) buf[j] = '\0'; if (NULL == (heap = H5HL_protect(f, H5P_DATASET_XFER_DEFAULT, heap_addr, H5AC_READ))) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } if (NULL == (s = H5HL_offset_into(f, heap, obj[i]))) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } if (strcmp(s, buf)) { H5_FAILED(); printf(" i=%d, heap offset=%lu\n", i, (unsigned long)(obj[i])); printf(" got: \"%s\"\n", s); printf(" ans: \"%s\"\n", buf); goto error; } if (H5HL_unprotect(f, H5P_DATASET_XFER_DEFAULT, heap, heap_addr) < 0) { H5_FAILED(); H5Eprint2(H5E_DEFAULT, stdout); goto error; } } if (H5Fclose(file)<0) goto error; PASSED(); puts("All local heap tests passed."); h5_cleanup(FILENAME, fapl); return 0; error: puts("*** TESTS FAILED ***"); H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; return 1; }