/*------------------------------------------------------------------------- * Function: H5I_init_group * * Purpose: Initialize an ID group whose ID number is specified by GRP, * If the group has already been initialized, this routine just * increments the count of number of initializations and returns * without trying to change the size of the hash table. A * specific number (RESERVED) of group entries may be reserved * to enable "constant" values to be handed out which are valid * IDs in the group, but which do not map to any data structures * and are not allocated dynamicly later. HASH_SIZE is the * minimum hash table size to use for the group. FREE_FUNC is * called with an object pointer when the object is removed from * the group. * * Return: Success: Non-negative * * Failure: Negative * * Programmer: Robb Matzke * Friday, February 19, 1999 * * Modifications: * Bill Wendling, 2000-05-05 * Instead of the ugly test of whether hash_size is a power of * two, I placed it in a macro POWER_OF_TWO which uses the fact * that a number that is a power of two has only 1 bit set. * * Bill Wendling, 2000-05-09 * Changed POWER_OF_TWO macro to allow 1 as a valid power of two. * Changed test below accordingly. * *------------------------------------------------------------------------- */ int H5I_init_group(H5I_type_t grp, size_t hash_size, unsigned reserved, H5I_free_t free_func) { H5I_id_group_t *grp_ptr = NULL; /*ptr to the atomic group*/ int ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI(H5I_init_group, FAIL); /* Check arguments */ if ((grp <= H5I_BADID || grp >= H5I_NGROUPS) && hash_size > 0) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number"); #ifdef HASH_SIZE_POWER_2 if (!POWER_OF_TWO(hash_size) || hash_size == 1) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid hash size"); #endif /* HASH_SIZE_POWER_2 */ if (H5I_id_group_list_g[grp] == NULL) { /* Allocate the group information for new group */ if (NULL==(grp_ptr = H5MM_calloc(sizeof(H5I_id_group_t)))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); H5I_id_group_list_g[grp] = grp_ptr; } else { /* Get the pointer to the existing group */ grp_ptr = H5I_id_group_list_g[grp]; } if (grp_ptr->count == 0) { /* Initialize the ID group structure for new groups */ grp_ptr->hash_size = hash_size; grp_ptr->reserved = reserved; grp_ptr->wrapped = 0; grp_ptr->ids = 0; grp_ptr->nextid = reserved; grp_ptr->free_func = free_func; grp_ptr->id_list = H5MM_calloc(hash_size*sizeof(H5I_id_info_t *)); if (NULL==grp_ptr->id_list) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } /* Increment the count of the times this group has been initialized */ grp_ptr->count++; done: if (ret_value<0) { /* Error condition cleanup */ if (grp_ptr != NULL) { H5MM_xfree(grp_ptr->id_list); H5MM_xfree(grp_ptr); } } FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_efl_copy * * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if * necessary. * * Return: Success: Ptr to _DEST * * Failure: NULL * * Programmer: Robb Matzke * Tuesday, November 25, 1997 * *------------------------------------------------------------------------- */ static void * H5O_efl_copy(const void *_mesg, void *_dest) { const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; H5O_efl_t *dest = (H5O_efl_t *) _dest; size_t u; /* Local index variable */ hbool_t slot_allocated = FALSE; /* Flag to indicate that dynamic allocation has begun */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* check args */ HDassert(mesg); /* Allocate destination message, if necessary */ if(!dest && NULL == (dest = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t)))) HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message") /* copy */ *dest = *mesg; /* Deep copy allocated information */ if(dest->nalloc > 0) { if(NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_calloc(dest->nalloc * sizeof(H5O_efl_entry_t)))) HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message slots") slot_allocated = TRUE; for(u = 0; u < mesg->nused; u++) { dest->slot[u] = mesg->slot[u]; if(NULL == (dest->slot[u].name = H5MM_xstrdup(mesg->slot[u].name))) HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message slot name") } /* end for */ } /* end if */ /* Set return value */ ret_value = dest; done: if(NULL == ret_value) { if(slot_allocated) { for(u = 0; u < dest->nused; u++) if(dest->slot[u].name != NULL && dest->slot[u].name != mesg->slot[u].name) dest->slot[u].name = (char *)H5MM_xfree(dest->slot[u].name); dest->slot = (H5O_efl_entry_t *)H5MM_xfree(dest->slot); } /* end if */ if(NULL == _dest) dest = (H5O_efl_t *)H5MM_xfree(dest); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_efl_copy() */
/*------------------------------------------------------------------------- * Function: H5I_destroy_group * * Purpose: Decrements the reference count on an entire group of IDs. * If the group reference count becomes zero then the group is * destroyed along with all atoms in that group regardless of * their reference counts. Destroying IDs involves calling * the free-func for each ID's object and then adding the ID * struct to the ID free list. * * Return: Non-negative on success/Negative on failure * * Programmer: Unknown * * Modifications: * * Robb Matzke, 25 Feb 1998 * IDs are freed when a group is destroyed. * *------------------------------------------------------------------------- */ herr_t H5I_destroy_group(H5I_type_t grp) { H5I_id_group_t *grp_ptr = NULL; /* ptr to the atomic group */ int ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5I_destroy_group, FAIL); if (grp <= H5I_BADID || grp >= H5I_NGROUPS) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid group number"); grp_ptr = H5I_id_group_list_g[grp]; if (grp_ptr == NULL || grp_ptr->count <= 0) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid group"); /* * Decrement the number of users of the atomic group. If this is the * last user of the group then release all atoms from the group. The * free function is invoked for each atom being freed. */ if (1==grp_ptr->count) { H5I_clear_group(grp, TRUE); H5E_clear(); /*don't care about errors*/ H5MM_xfree(grp_ptr->id_list); HDmemset (grp_ptr, 0, sizeof(*grp_ptr)); } else { --(grp_ptr->count); } done: FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_drvinfo_copy * * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if * necessary. * * Return: Success: Ptr to _DEST * Failure: NULL * * Programmer: Quincey Koziol * Mar 1, 2007 * *------------------------------------------------------------------------- */ static void * H5O_drvinfo_copy(const void *_mesg, void *_dest) { const H5O_drvinfo_t *mesg = (const H5O_drvinfo_t *)_mesg; H5O_drvinfo_t *dest = (H5O_drvinfo_t *)_dest; void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity check */ HDassert(mesg); if(!dest && NULL == (dest = (H5O_drvinfo_t *)H5MM_malloc(sizeof(H5O_drvinfo_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for shared message table message") /* Shallow copy the fields */ *dest = *mesg; /* Copy the buffer */ if(NULL == (dest->buf = (uint8_t *)H5MM_malloc(mesg->len))) { if(dest != _dest) dest = (H5O_drvinfo_t *)H5MM_xfree(dest); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") } /* end if */ HDmemcpy(dest->buf, mesg->buf, mesg->len); /* Set return value */ ret_value = dest; done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_drvinfo_copy() */
/*------------------------------------------------------------------------- * Function: H5MM_realloc * * Purpose: Just like the POSIX version of realloc(3). Specifically, the * following calls are equivalent * * H5MM_realloc (NULL, size) <==> H5MM_malloc (size) * H5MM_realloc (ptr, 0) <==> H5MM_xfree (ptr) * H5MM_realloc (NULL, 0) <==> NULL * * Return: Success: Ptr to new memory or NULL if the memory * was freed. * * Failure: abort() * * Programmer: Robb Matzke * [email protected] * Jul 10 1997 * * Modifications: * *------------------------------------------------------------------------- */ void * H5MM_realloc(void *mem, size_t size) { void *ret_value; /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_realloc); if (!mem) { if (0 == size) HGOTO_DONE(NULL); mem = H5MM_malloc(size); } else if (0 == size) { mem = H5MM_xfree(mem); } else { mem = HDrealloc(mem, size); assert(mem); } /* Set return value */ ret_value=mem; done: FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_fill_decode * * Purpose: Decode a fill value message. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * * Programmer: Robb Matzke * Wednesday, September 30, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static void * H5O_fill_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p) { H5O_fill_t *mesg=NULL; void *ret_value; FUNC_ENTER_NOAPI_NOINIT(H5O_fill_decode); assert(f); assert(p); if (NULL==(mesg=H5FL_CALLOC(H5O_fill_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message"); UINT32DECODE(p, mesg->size); if (mesg->size>0) { if (NULL==(mesg->buf=H5MM_malloc(mesg->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value"); HDmemcpy(mesg->buf, p, mesg->size); } /* Set return value */ ret_value = (void*)mesg; done: if (!ret_value && mesg) { if(mesg->buf) H5MM_xfree(mesg->buf); H5FL_FREE(H5O_fill_t,mesg); } FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_name_copy * * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if * necessary. * * Return: Success: Ptr to _DEST * * Failure: NULL * * Programmer: Robb Matzke * [email protected] * Aug 12 1997 * * Modifications: * *------------------------------------------------------------------------- */ static void * H5O_name_copy(const void *_mesg, void *_dest) { const H5O_name_t *mesg = (const H5O_name_t *) _mesg; H5O_name_t *dest = (H5O_name_t *) _dest; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* check args */ HDassert(mesg); if(!dest && NULL == (dest = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* copy */ *dest = *mesg; if(NULL == (dest->s = H5MM_xstrdup(mesg->s))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Set return value */ ret_value = dest; done: if(NULL == ret_value) if(dest && NULL == _dest) dest = (H5O_name_t *)H5MM_xfree(dest); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_name_copy() */
/*------------------------------------------------------------------------- * Function: H5O_bogus_decode * * Purpose: Decode a "bogus" message and return a pointer to a new * native message struct. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * * Programmer: Quincey Koziol * [email protected] * Jan 21 2003 * *------------------------------------------------------------------------- */ static void * H5O_bogus_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p) { H5O_bogus_t *mesg = NULL; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_bogus_decode) /* check args */ HDassert(f); HDassert(p); /* Allocate the bogus message */ if(NULL == (mesg = H5MM_calloc(sizeof(H5O_bogus_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* decode */ UINT32DECODE(p, mesg->u); /* Validate the bogus info */ if(mesg->u != H5O_BOGUS_VALUE) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "invalid bogus value :-)") /* Set return value */ ret_value = mesg; done: if(ret_value == NULL && mesg != NULL) H5MM_xfree(mesg); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_bogus_decode() */
/*------------------------------------------------------------------------- * Function: H5I_term_interface * * Purpose: Terminate the H5I interface: release all memory, reset all * global variables to initial values. This only happens if all * groups have been destroyed from other interfaces. * * Return: Success: Positive if any action was taken that might * affect some other interface; zero otherwise. * * Failure: Negative. * * Programmer: * * Modifications: * *------------------------------------------------------------------------- */ int H5I_term_interface(void) { H5I_id_group_t *grp_ptr; H5I_type_t grp; int n=0; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5I_term_interface); if (H5_interface_initialize_g) { /* How many groups are still being used? */ for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; H5_INC_ENUM(H5I_type_t,grp)) { if ((grp_ptr=H5I_id_group_list_g[grp]) && grp_ptr->id_list) n++; } /* If no groups are used then clean up */ if (0==n) { for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; H5_INC_ENUM(H5I_type_t,grp)) { grp_ptr = H5I_id_group_list_g[grp]; H5MM_xfree(grp_ptr); H5I_id_group_list_g[grp] = NULL; } } /* Mark interface closed */ H5_interface_initialize_g = 0; } FUNC_LEAVE_NOAPI(n); }
/*------------------------------------------------------------------------- * Function: H5G__link_release_table * * Purpose: Release table containing a list of links for a group * * Return: Success: Non-negative * Failure: Negative * * Programmer: Quincey Koziol * Sep 6, 2005 * *------------------------------------------------------------------------- */ herr_t H5G__link_release_table(H5G_link_table_t *ltable) { size_t u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Sanity check */ HDassert(ltable); /* Release link info, if any */ if(ltable->nlinks > 0) { /* Free link message information */ for(u = 0; u < ltable->nlinks; u++) if(H5O_msg_reset(H5O_LINK_ID, &(ltable->lnks[u])) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link message") /* Free table of links */ H5MM_xfree(ltable->lnks); } /* end if */ else HDassert(ltable->lnks == NULL); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__link_release_table() */
/*------------------------------------------------------------------------- * Function: H5O_name_decode * * Purpose: Decode a name message and return a pointer to a new * native message struct. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * * Programmer: Robb Matzke * [email protected] * Aug 12 1997 * *------------------------------------------------------------------------- */ static void * H5O_name_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) { H5O_name_t *mesg; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* check args */ HDassert(f); HDassert(p); /* decode */ if(NULL == (mesg = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(NULL == (mesg->s = (char *)H5MM_strdup((const char *)p))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Set return value */ ret_value = mesg; done: if(NULL == ret_value) { if(mesg) mesg = (H5O_name_t *)H5MM_xfree(mesg); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_name_decode() */
/*------------------------------------------------------------------------- * Function: H5O_name_decode * * Purpose: Decode a name message and return a pointer to a new * native message struct. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * * Programmer: Robb Matzke * [email protected] * Aug 12 1997 * *------------------------------------------------------------------------- */ static void * H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, unsigned UNUSED mesg_flags, const uint8_t *p) { H5O_name_t *mesg; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_name_decode); /* check args */ assert(f); assert(p); /* decode */ if (NULL==(mesg = H5MM_calloc(sizeof(H5O_name_t))) || NULL==(mesg->s = H5MM_malloc (HDstrlen((const char*)p)+1))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); HDstrcpy(mesg->s, (const char*)p); /* Set return value */ ret_value=mesg; done: if(ret_value==NULL) { if(mesg) H5MM_xfree (mesg); } /* end if */ FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_fill_new_decode * * Purpose: Decode a new fill value message. The new fill value * message is fill value plus space allocation time and * fill value writing time and whether fill value is defined. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * * Programmer: Raymond Lu * Feb 26, 2002 * * Modifications: * *------------------------------------------------------------------------- */ static void * H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p) { H5O_fill_new_t *mesg=NULL; int version; void *ret_value; FUNC_ENTER_NOAPI_NOINIT(H5O_fill_new_decode); assert(f); assert(p); if (NULL==(mesg=H5FL_CALLOC(H5O_fill_new_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message"); /* Version */ version = *p++; if( version != H5O_FILL_VERSION && version !=H5O_FILL_VERSION_2) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for fill value message"); /* Space allocation time */ mesg->alloc_time = (H5D_alloc_time_t)*p++; /* Fill value write time */ mesg->fill_time = (H5D_fill_time_t)*p++; /* Whether fill value is defined */ mesg->fill_defined = *p++; /* Only decode fill value information if one is defined */ if(mesg->fill_defined) { INT32DECODE(p, mesg->size); if (mesg->size>0) { H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t); if (NULL==(mesg->buf=H5MM_malloc((size_t)mesg->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value"); HDmemcpy(mesg->buf, p, (size_t)mesg->size); } } /* end if */ else mesg->size=(-1); /* Set return value */ ret_value = (void*)mesg; done: if (!ret_value && mesg) { if(mesg->buf) H5MM_xfree(mesg->buf); H5FL_FREE(H5O_fill_new_t,mesg); } FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5G_namei_term_interface * * Purpose: Terminates part of the H5G interface - free the global * component buffer. * * Return: Success: Non-negative. * * Failure: Negative. * * Programmer: Quincey Koziol * Monday, September 26, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_namei_term_interface(void) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_namei_term_interface) /* Free the global component buffer */ H5G_comp_g = H5MM_xfree(H5G_comp_g); H5G_comp_alloc_g = 0; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_namei_term_interface() */
/*------------------------------------------------------------------------- * Function: H5O__drvinfo_reset * * Purpose: Frees internal pointers and resets the message to an * initial state. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Mar 1 2007 * *------------------------------------------------------------------------- */ static herr_t H5O__drvinfo_reset(void *_mesg) { H5O_drvinfo_t *mesg = (H5O_drvinfo_t *) _mesg; FUNC_ENTER_STATIC_NOERR /* check args */ HDassert(mesg); /* reset */ mesg->buf = (uint8_t *)H5MM_xfree(mesg->buf); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O__drvinfo_reset() */
/*------------------------------------------------------------------------- * Function: H5O_name_reset * * Purpose: Frees internal pointers and resets the message to an * initial state. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * [email protected] * Aug 12 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5O_name_reset(void *_mesg) { H5O_name_t *mesg = (H5O_name_t *) _mesg; FUNC_ENTER_NOAPI_NOINIT_NOERR /* check args */ HDassert(mesg); /* reset */ mesg->s = (char *)H5MM_xfree(mesg->s); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_name_reset() */
/*------------------------------------------------------------------------- * Function: H5O_name_reset * * Purpose: Frees internal pointers and resets the message to an * initial state. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * [email protected] * Aug 12 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5O_name_reset(void *_mesg) { H5O_name_t *mesg = (H5O_name_t *) _mesg; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_name_reset); /* check args */ assert(mesg); /* reset */ mesg->s = H5MM_xfree(mesg->s); FUNC_LEAVE_NOAPI(SUCCEED); }
/*------------------------------------------------------------------------- * Function: H5O_efl_reset * * Purpose: Frees internal pointers and resets the message to an * initialial state. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Tuesday, November 25, 1997 * *------------------------------------------------------------------------- */ static herr_t H5O_efl_reset(void *_mesg) { H5O_efl_t *mesg = (H5O_efl_t *) _mesg; size_t u; /* Local index variable */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* check args */ HDassert(mesg); /* reset */ if(mesg->slot) { for(u = 0; u < mesg->nused; u++) { mesg->slot[u].name = (char *)H5MM_xfree(mesg->slot[u].name); mesg->slot[u].name_offset = 0; } /* end for */ mesg->slot = (H5O_efl_entry_t *)H5MM_xfree(mesg->slot); } /* end if */ mesg->heap_addr = HADDR_UNDEF; mesg->nused = mesg->nalloc = 0; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_efl_reset() */
/*------------------------------------------------------------------------- * Function: H5O_layout_reset * * Purpose: Frees resources within a data type message, but doesn't free * the message itself. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Friday, September 13, 2002 * *------------------------------------------------------------------------- */ static herr_t H5O_layout_reset(void *_mesg) { H5O_layout_t *mesg = (H5O_layout_t *)_mesg; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_layout_reset) if(mesg) { /* Free the compact storage buffer */ if(H5D_COMPACT == mesg->type) mesg->storage.u.compact.buf = H5MM_xfree(mesg->storage.u.compact.buf); /* Reset the message */ mesg->type = H5D_CONTIGUOUS; } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_layout_reset() */
/*------------------------------------------------------------------------- * Function: H5MP_close * * Purpose: Release all memory for a pool and destroy pool * * Return: Non-negative on success/negative on failure * * Programmer: Quincey Koziol * [email protected] * May 3 2005 * *------------------------------------------------------------------------- */ herr_t H5MP_close (H5MP_pool_t *mp) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5MP_close, FAIL) /* Release memory for pool pages */ if(mp->first != NULL) { H5MP_page_t *page, *next_page; /* Pointer to pages in pool */ /* Iterate through pages, releasing them */ page = mp->first; while(page) { next_page = page->next; /* Free the page appropriately */ if(page->fac_alloc) H5FL_FAC_FREE(mp->page_fac,page); else H5MM_xfree(page); page = next_page; } /* end while */ } /* end if */ /* Release page factory */ if(mp->page_fac) if(H5FL_fac_term(mp->page_fac)<0) HGOTO_ERROR (H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy page factory") /* Free the memory pool itself */ H5FL_FREE(H5MP_pool_t, mp); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5MP_close() */
/*------------------------------------------------------------------------- * Function: H5MM_realloc * * Purpose: Just like the POSIX version of realloc(3). Specifically, the * following calls are equivalent * * H5MM_realloc (NULL, size) <==> H5MM_malloc (size) * H5MM_realloc (ptr, 0) <==> H5MM_xfree (ptr) * H5MM_realloc (NULL, 0) <==> NULL * * Return: Success: Ptr to new memory or NULL if the memory * was freed. * * Failure: NULL * * Programmer: Robb Matzke * [email protected] * Jul 10 1997 * *------------------------------------------------------------------------- */ void * H5MM_realloc(void *mem, size_t size) { void *ret_value; /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_realloc) if(NULL == mem) { if(0 == size) mem = NULL; else mem = H5MM_malloc(size); } /* end if */ else if(0 == size) mem = H5MM_xfree(mem); else mem = HDrealloc(mem, size); /* Set return value */ ret_value = mem; FUNC_LEAVE_NOAPI(ret_value) } /* end H5MM_realloc() */
/*------------------------------------------------------------------------- * Function: H5O_drvinfo_decode * * Purpose: Decode a shared message table message and return a pointer * to a newly allocated H5O_drvinfo_t struct. * * Return: Success: Ptr to new message in native struct. * Failure: NULL * * Programmer: Quincey Koziol * Mar 1, 2007 * *------------------------------------------------------------------------- */ static void * H5O_drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) { H5O_drvinfo_t *mesg; /* Native message */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity check */ HDassert(f); HDassert(p); /* Version of message */ if(*p++ != H5O_DRVINFO_VERSION) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") /* Allocate space for message */ if(NULL == (mesg = (H5O_drvinfo_t *)H5MM_calloc(sizeof(H5O_drvinfo_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info message") /* Retrieve driver name */ HDmemcpy(mesg->name, p, 8); mesg->name[8] = '\0'; p += 8; /* Decode buffer size */ UINT16DECODE(p, mesg->len); HDassert(mesg->len); /* Allocate space for buffer */ if(NULL == (mesg->buf = (uint8_t *)H5MM_malloc(mesg->len))) { mesg = (H5O_drvinfo_t *)H5MM_xfree(mesg); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info buffer") } /* end if */
/*------------------------------------------------------------------------- * Function: H5G_link_copy_file * * Purpose: Copy a link and the object it points to from one file to * another. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * [email protected] * Sep 29 2006 * *------------------------------------------------------------------------- */ herr_t H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, H5O_link_t *dst_lnk, H5O_copy_t *cpy_info) { H5O_link_t tmp_src_lnk; /* Temporary copy of src link, when needed */ const H5O_link_t *src_lnk = _src_lnk; /* Source link */ hbool_t dst_lnk_init = FALSE; /* Whether the destination link is initialized */ hbool_t expanded_link_open = FALSE; /* Whether the target location has been opened */ H5G_loc_t tmp_src_loc; /* Group location holding target object */ H5G_name_t tmp_src_path; /* Path for target object */ H5O_loc_t tmp_src_oloc; /* Object location for target object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_link_copy_file, FAIL) /* check arguments */ HDassert(dst_file); HDassert(src_lnk); HDassert(dst_lnk); HDassert(cpy_info); /* Expand soft or external link, if requested */ if((H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link) || (H5L_TYPE_EXTERNAL == src_lnk->type && cpy_info->expand_ext_link)) { H5G_loc_t lnk_grp_loc; /* Group location holding link */ H5G_name_t lnk_grp_path; /* Path for link */ htri_t tar_exists; /* Whether the target object exists */ /* Set up group location for link */ H5G_name_reset(&lnk_grp_path); lnk_grp_loc.path = &lnk_grp_path; lnk_grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */ /* Check if the target object exists */ if((tar_exists = H5G_loc_exists(&lnk_grp_loc, src_lnk->name, H5P_DEFAULT, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to check if target object exists") if(tar_exists) { /* Make a temporary copy of the link, so that it will not change the * info in the cache when we change it to a hard link */ if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, &tmp_src_lnk)) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy message") /* Set up group location for target object. Let H5G_traverse expand * the link. */ tmp_src_loc.path = &tmp_src_path; tmp_src_loc.oloc = &tmp_src_oloc; if(H5G_loc_reset(&tmp_src_loc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to reset location") /* Find the target object */ if(H5G_loc_find(&lnk_grp_loc, src_lnk->name, &tmp_src_loc, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to find target object") expanded_link_open = TRUE; /* Convert symbolic link to hard link */ if(tmp_src_lnk.type == H5L_TYPE_SOFT) tmp_src_lnk.u.soft.name = (char *)H5MM_xfree(tmp_src_lnk.u.soft.name); else if(tmp_src_lnk.u.ud.size > 0) tmp_src_lnk.u.ud.udata = H5MM_xfree(tmp_src_lnk.u.ud.udata); tmp_src_lnk.type = H5L_TYPE_HARD; tmp_src_lnk.u.hard.addr = tmp_src_oloc.addr; src_lnk = &tmp_src_lnk; } /* end if */ } /* end if */
/*------------------------------------------------------------------------- * Function: H5O_efl_copy_file * * Purpose: Copies an efl message from _MESG to _DEST in file * * Return: Success: Ptr to _DEST * * Failure: NULL * * Programmer: Peter Cao * September 29, 2005 * *------------------------------------------------------------------------- */ static void * H5O_efl_copy_file(H5F_t H5_ATTR_UNUSED *file_src, void *mesg_src, H5F_t *file_dst, hbool_t H5_ATTR_UNUSED *recompute_size, unsigned H5_ATTR_UNUSED *mesg_flags, H5O_copy_t H5_ATTR_UNUSED *cpy_info, void H5_ATTR_UNUSED *_udata, hid_t dxpl_id) { H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src; H5O_efl_t *efl_dst = NULL; H5HL_t *heap = NULL; /* Pointer to local heap for EFL file names */ size_t idx, size, name_offset, heap_size; void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, H5AC__COPIED_TAG, NULL) /* check args */ HDassert(efl_src); HDassert(file_dst); /* Allocate space for the destination efl */ if(NULL == (efl_dst = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the "top level" information */ HDmemcpy(efl_dst, efl_src, sizeof(H5O_efl_t)); /* Determine size needed for destination heap */ heap_size = H5HL_ALIGN(1); /* "empty" name */ for(idx = 0; idx < efl_src->nused; idx++) heap_size += H5HL_ALIGN(HDstrlen(efl_src->slot[idx].name) + 1); /* Create name heap */ if(H5HL_create(file_dst, dxpl_id, heap_size, &efl_dst->heap_addr/*out*/) < 0) HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, NULL, "can't create heap") /* Pin the heap down in memory */ if(NULL == (heap = H5HL_protect(file_dst, dxpl_id, efl_dst->heap_addr, H5AC__NO_FLAGS_SET))) HGOTO_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to protect EFL file name heap") /* Insert "empty" name first */ if((size_t)(-1) == (name_offset = H5HL_insert(file_dst, dxpl_id, heap, (size_t)1, ""))) HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap") HDassert(0 == name_offset); /* allocate array of external file entries */ if(efl_src->nalloc > 0) { size = efl_src->nalloc * sizeof(H5O_efl_entry_t); if((efl_dst->slot = (H5O_efl_entry_t *)H5MM_calloc(size)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* copy content from the source. Need to update later */ HDmemcpy(efl_dst->slot, efl_src->slot, size); } /* end if */ /* copy the name from the source */ for(idx = 0; idx < efl_src->nused; idx++) { efl_dst->slot[idx].name = H5MM_xstrdup(efl_src->slot[idx].name); if((size_t)(-1) == (efl_dst->slot[idx].name_offset = H5HL_insert(file_dst, dxpl_id, heap, HDstrlen(efl_dst->slot[idx].name) + 1, efl_dst->slot[idx].name))) HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap") } /* end for */ /* Set return value */ ret_value = efl_dst; done: /* Release resources */ if(heap && H5HL_unprotect(heap) < 0) HDONE_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to unprotect EFL file name heap") if(!ret_value) if(efl_dst) H5MM_xfree(efl_dst); FUNC_LEAVE_NOAPI_TAG(ret_value, NULL) } /* end H5O_efl_copy_file() */
/*------------------------------------------------------------------------- * 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); }
/*-------------------------------------------------------------------------- NAME H5R__create PURPOSE Creates a particular kind of reference for the user USAGE herr_t H5R__create(ref, loc, name, ref_type, space) void *ref; OUT: Reference created H5G_loc_t *loc; IN: File location used to locate object pointed to const char *name; IN: Name of object at location LOC_ID of object pointed to H5R_type_t ref_type; IN: Type of reference to create H5S_t *space; IN: Dataspace ID with selection, used for Dataset Region references. RETURNS Non-negative on success/Negative on failure DESCRIPTION Creates a particular type of reference specified with REF_TYPE, in the space pointed to by REF. The LOC_ID and NAME are used to locate the object pointed to and the SPACE_ID is used to choose the region pointed to (for Dataset Region references). GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ herr_t H5R__create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space) { H5G_loc_t obj_loc; /* Group hier. location of object */ H5G_name_t path; /* Object group hier. path */ H5O_loc_t oloc; /* Object object location */ hbool_t obj_found = FALSE; /* Object location found */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_VOL HDassert(_ref); HDassert(loc); HDassert(name); HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); /* Set up object location to fill in */ obj_loc.oloc = &oloc; obj_loc.path = &path; H5G_loc_reset(&obj_loc); /* Find the object */ if(H5G_loc_find(loc, name, &obj_loc) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") obj_found = TRUE; switch (ref_type) { case H5R_OBJECT: { hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */ *ref = obj_loc.oloc->addr; break; } case H5R_DATASET_REGION: { H5HG_t hobjid; /* Heap object ID */ hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ hssize_t buf_size; /* Size of buffer needed to serialize selection */ uint8_t *p; /* Pointer to OID to store */ uint8_t *buf; /* Buffer to store serialized selection in */ unsigned heapid_found; /* Flag for non-zero heap ID found */ unsigned u; /* local index */ /* Set up information for dataset region */ /* Return any previous heap block to the free list if we are * garbage collecting */ if (H5F_GC_REF(loc->oloc->file)) { /* Check for an existing heap ID in the reference */ for (u = 0, heapid_found = 0, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++) if (p[u] != 0) { heapid_found = 1; break; } if (heapid_found != 0) { /* Return heap block to free list */ } } /* Zero the heap ID out, may leak heap space if user is re-using * reference and doesn't have garbage collection turned on */ HDmemset(ref, 0, H5R_DSET_REG_REF_BUF_SIZE); /* Get the amount of space required to serialize the selection */ if ((buf_size = H5S_SELECT_SERIAL_SIZE(space, loc->oloc->file)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection") /* Increase buffer size to allow for the dataset OID */ buf_size += (hssize_t)sizeof(haddr_t); /* Allocate the space to store the serialized information */ H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); if (NULL == (buf = (uint8_t *)H5MM_malloc((size_t)buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Serialize information for dataset OID into heap buffer */ p = (uint8_t *)buf; H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); /* Serialize the selection into heap buffer */ if (H5S_SELECT_SERIALIZE(space, &p, loc->oloc->file) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") /* Save the serialized buffer for later */ H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); if(H5HG_insert(loc->oloc->file, (size_t)buf_size, buf, &hobjid) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection") /* Serialize the heap ID and index for storage in the file */ p = (uint8_t *)ref; H5F_addr_encode(loc->oloc->file, &p, hobjid.addr); UINT32ENCODE(p, hobjid.idx); /* Free the buffer we serialized data in */ H5MM_xfree(buf); break; } /* end case H5R_DATASET_REGION */ case H5R_BADTYPE: case H5R_MAXTYPE: default: HDassert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ done: if (obj_found) H5G_loc_free(&obj_loc); FUNC_LEAVE_NOAPI_VOL(ret_value) } /* end H5R__create() */
/*-------------------------------------------------------------------------- NAME H5R__dereference PURPOSE Opens the HDF5 object referenced. USAGE hid_t H5R__dereference(ref, oapl_id, ref_type, ref) H5F_t *file; IN: File the object being dereferenced is within hid_t oapl_id; IN: Object access property list ID H5R_type_t ref_type; IN: Type of reference void *ref; IN: Reference to open. RETURNS Valid ID on success, Negative on failure DESCRIPTION Given a reference to some object, open that object and return an ID for that object. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS Currently only set up to work with references to datasets EXAMPLES REVISION LOG Raymond Lu 13 July 2011 I added the OAPL_ID parameter for the object being referenced. It only supports dataset access property list currently. M. Scot Breitenfeld 3 March 2015 Added a check for undefined reference pointer. --------------------------------------------------------------------------*/ hid_t H5R__dereference(H5F_t *file, hid_t oapl_id, H5R_type_t ref_type, const void *_ref) { H5O_loc_t oloc; /* Object location */ H5G_name_t path; /* Path of object */ H5G_loc_t loc; /* Group location */ unsigned rc; /* Reference count of object */ H5O_type_t obj_type; /* Type of object */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_PACKAGE_VOL HDassert(_ref); HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); HDassert(file); /* Initialize the object location */ H5O_loc_reset(&oloc); oloc.file = file; switch (ref_type) { case H5R_OBJECT: { oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ if (!H5F_addr_defined(oloc.addr) || oloc.addr == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer") break; } case H5R_DATASET_REGION: { H5HG_t hobjid; /* Heap object ID */ uint8_t *buf; /* Buffer to store serialized selection in */ const uint8_t *p; /* Pointer to OID to store */ /* Get the heap ID for the dataset region */ p = (const uint8_t *)_ref; H5F_addr_decode(oloc.file, &p, &(hobjid.addr)); UINT32DECODE(p, hobjid.idx); if (!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer") /* Get the dataset region from the heap (allocate inside routine) */ if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL))) HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5I_INVALID_HID, "Unable to read dataset region information") /* Get the object oid for the dataset */ p = buf; H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Free the buffer allocated in H5HG_read() */ H5MM_xfree(buf); break; } /* end case H5R_DATASET_REGION */ case H5R_BADTYPE: case H5R_MAXTYPE: default: HDassert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5I_INVALID_HID, "internal error (unknown reference type)") } /* end switch */ /* Get the # of links for object, and its type * (To check to make certain that this object hasn't been deleted * since the reference was created) */ if(H5O_get_rc_and_type(&oloc, &rc, &obj_type) < 0 || 0 == rc) HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5I_INVALID_HID, "dereferencing deleted object") /* Construct a group location for opening the object */ H5G_name_reset(&path); loc.oloc = &oloc; loc.path = &path; /* Open the object */ switch (obj_type) { case H5O_TYPE_GROUP: { H5G_t *group; /* Pointer to group to open */ if(NULL == (group = H5G_open(&loc))) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5I_INVALID_HID, "not found") /* Create an atom for the group */ if((ret_value = H5I_register(H5I_GROUP, group, TRUE)) < 0) { H5G_close(group); HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register group") } /* end if */ break; } case H5O_TYPE_NAMED_DATATYPE: { H5T_t *type; /* Pointer to datatype to open */ if(NULL == (type = H5T_open(&loc))) HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, H5I_INVALID_HID, "not found") /* Create an atom for the datatype */ if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0) { H5T_close(type); HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register datatype") } /* end if */ break; }
/*------------------------------------------------------------------------- * Function: H5HL_debug * * Purpose: Prints debugging information about a heap. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * [email protected] * Aug 1 1997 * * Modifications: * Robb Matzke, 1999-07-28 * The ADDR argument is passed by value. *------------------------------------------------------------------------- */ herr_t H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth) { H5HL_t *h = NULL; int i, j, overlap, free_block; uint8_t c; H5HL_free_t *freelist = NULL; uint8_t *marker = NULL; size_t amount_free = 0; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HL_debug, FAIL); /* check arguments */ assert(f); assert(H5F_addr_defined(addr)); assert(stream); assert(indent >= 0); assert(fwidth >= 0); if (NULL == (h = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap"); fprintf(stream, "%*sLocal Heap...\n", indent, ""); fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, "Dirty:", (int) (h->cache_info.is_dirty)); fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, "Header size (in bytes):", (unsigned long) H5HL_SIZEOF_HDR(f)); HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of heap data:", h->addr); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Data bytes allocated on disk:", h->disk_alloc); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Data bytes allocated in core:", h->mem_alloc); /* * Traverse the free list and check that all free blocks fall within * the heap and that no two free blocks point to the same region of * the heap. */ if (NULL==(marker = H5MM_calloc(h->mem_alloc))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); fprintf(stream, "%*sFree Blocks (offset, size):\n", indent, ""); for (free_block=0, freelist = h->freelist; freelist; freelist = freelist->next, free_block++) { char temp_str[32]; sprintf(temp_str,"Block #%d:",free_block); HDfprintf(stream, "%*s%-*s %8Zu, %8Zu\n", indent+3, "", MAX(0,fwidth-9), temp_str, freelist->offset, freelist->size); if (freelist->offset + freelist->size > h->mem_alloc) { fprintf(stream, "***THAT FREE BLOCK IS OUT OF BOUNDS!\n"); } else { for (i=overlap=0; i<(int)(freelist->size); i++) { if (marker[freelist->offset + i]) overlap++; marker[freelist->offset + i] = 1; } if (overlap) { fprintf(stream, "***THAT FREE BLOCK OVERLAPPED A PREVIOUS " "ONE!\n"); } else { amount_free += freelist->size; } } } if (h->mem_alloc) { fprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth, "Percent of heap used:", (100.0 * (double)(h->mem_alloc - amount_free) / (double)h->mem_alloc)); } /* * Print the data in a VMS-style octal dump. */ fprintf(stream, "%*sData follows (`__' indicates free region)...\n", indent, ""); for (i=0; i<(int)(h->disk_alloc); i+=16) { fprintf(stream, "%*s %8d: ", indent, "", i); for (j = 0; j < 16; j++) { if (i+j<(int)(h->disk_alloc)) { if (marker[i + j]) { fprintf(stream, "__ "); } else { c = h->chunk[H5HL_SIZEOF_HDR(f) + i + j]; fprintf(stream, "%02x ", c); } } else { fprintf(stream, " "); } if (7 == j) HDfputc(' ', stream); } for (j = 0; j < 16; j++) { if (i+j < (int)(h->disk_alloc)) { if (marker[i + j]) { HDfputc(' ', stream); } else { c = h->chunk[H5HL_SIZEOF_HDR(f) + i + j]; if (c > ' ' && c < '~') HDfputc(c, stream); else HDfputc('.', stream); } } } HDfputc('\n', stream); } done: if (h && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, h, FALSE) != SUCCEED) HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header"); H5MM_xfree(marker); FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5HL_debug * * Purpose: Prints debugging information about a heap. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * [email protected] * Aug 1 1997 * * Modifications: * Robb Matzke, 1999-07-28 * The ADDR argument is passed by value. * * John Mainzer, 6/17/05 * Modified the function to use the new dirtied parameter of * of H5AC_unprotect() instead of modifying the is_dirty * field of the cache info. * *------------------------------------------------------------------------- */ herr_t H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth) { H5HL_t *h = NULL; int i, overlap, free_block; H5HL_free_t *freelist = NULL; uint8_t *marker = NULL; size_t amount_free = 0; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HL_debug, FAIL) /* check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(stream); HDassert(indent >= 0); HDassert(fwidth >= 0); if(NULL == (h = (H5HL_t *)H5HL_protect(f, dxpl_id, addr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap") fprintf(stream, "%*sLocal Heap...\n", indent, ""); fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, "Header size (in bytes):", (unsigned long)h->prfx_size); HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of heap data:", h->dblk_addr); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Data bytes allocated for heap:", h->dblk_size); /* * Traverse the free list and check that all free blocks fall within * the heap and that no two free blocks point to the same region of * the heap. */ if(NULL == (marker = (uint8_t *)H5MM_calloc(h->dblk_size))) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") fprintf(stream, "%*sFree Blocks (offset, size):\n", indent, ""); for(free_block = 0, freelist = h->freelist; freelist; freelist = freelist->next, free_block++) { char temp_str[32]; sprintf(temp_str,"Block #%d:",free_block); HDfprintf(stream, "%*s%-*s %8Zu, %8Zu\n", indent+3, "", MAX(0,fwidth-9), temp_str, freelist->offset, freelist->size); if((freelist->offset + freelist->size) > h->dblk_size) fprintf(stream, "***THAT FREE BLOCK IS OUT OF BOUNDS!\n"); else { for(i = overlap = 0; i < (int)(freelist->size); i++) { if(marker[freelist->offset + i]) overlap++; marker[freelist->offset + i] = 1; } /* end for */ if(overlap) fprintf(stream, "***THAT FREE BLOCK OVERLAPPED A PREVIOUS ONE!\n"); else amount_free += freelist->size; } /* end for */ } /* end for */ if(h->dblk_size) fprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth, "Percent of heap used:", (100.0 * (double)(h->dblk_size - amount_free) / (double)h->dblk_size)); /* * Print the data in a VMS-style octal dump. */ H5_buffer_dump(stream, indent, h->dblk_image, marker, (size_t)0, h->dblk_size); done: if(h && H5HL_unprotect(h) < 0) HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") H5MM_xfree(marker); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HL_debug() */
/*------------------------------------------------------------------------- * 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() */