Ejemplo n.º 1
0
/*--------------------------------------------------------------------------
 NAME
    H5O_attr_decode
 PURPOSE
    Decode a attribute message and return a pointer to a memory struct
        with the decoded information
 USAGE
    void *H5O_attr_decode(f, dxpl_id, mesg_flags, p)
        H5F_t *f;               IN: pointer to the HDF5 file struct
        hid_t dxpl_id;          IN: DXPL for any I/O
        unsigned mesg_flags;    IN: Message flags to influence decoding
        const uint8_t *p;       IN: the raw information buffer
 RETURNS
    Pointer to the new message in native order on success, NULL on failure
 DESCRIPTION
        This function decodes the "raw" disk form of a attribute message
    into a struct in memory native format.  The struct is allocated within this
    function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
    unsigned *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p)
{
    H5A_t		*attr = NULL;
    H5S_extent_t	*extent;	/*extent dimensionality information  */
    size_t		name_len;   	/*attribute name length */
    unsigned            flags = 0;      /* Attribute flags */
    H5A_t		*ret_value;     /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(f);
    HDassert(p);

    if(NULL == (attr = H5FL_CALLOC(H5A_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
        HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")

    /* Version number */
    attr->shared->version = *p++;
    if(attr->shared->version < H5O_ATTR_VERSION_1 || attr->shared->version > H5O_ATTR_VERSION_LATEST)
	HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "bad version number for attribute message")

    /* Get the flags byte if we have a later version of the attribute */
    if(attr->shared->version >= H5O_ATTR_VERSION_2) {
        flags = *p++;

        /* Check for unknown flag */
        if(flags & (unsigned)~H5O_ATTR_FLAG_ALL)
            HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "unknown flag for attribute message")
    } /* end if */
Ejemplo n.º 2
0
/*-------------------------------------------------------------------------
 * Function:    H5F_fake_alloc
 *
 * Purpose:     Allocate a "fake" file structure, for various routines to
 *              use for encoding/decoding data structures using internal API
 *              routines that need a file structure, but don't ultimately
 *              depend on having a "real" file.
 *
 * Return:      Success:        Pointer to 'faked up' file structure
 *              Failure:        NULL
 *
 * Programmer:  Quincey Koziol
 *              [email protected]
 *              Oct  2, 2006
 *
 *-------------------------------------------------------------------------
 */
H5F_t *
H5F_fake_alloc(uint8_t sizeof_size)
{
    H5F_t *f = NULL;            /* Pointer to fake file struct */
    H5F_t *ret_value;           /* Return value */

    FUNC_ENTER_NOAPI(NULL)

    /* Allocate faked file struct */
    if(NULL == (f = H5FL_CALLOC(H5F_t)))
	HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate top file structure")
    if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t)))
	HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure")

    /* Only set fields necessary for clients */
    if(sizeof_size == 0)
        f->shared->sizeof_size = H5F_OBJ_SIZE_SIZE;
    else
        f->shared->sizeof_size = sizeof_size;

    /* Set return value */
    ret_value = f;

done:
    if(!ret_value)
        H5F_fake_free(f);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_fake_alloc() */
Ejemplo n.º 3
0
/*-------------------------------------------------------------------------
 * Function:	H5G__create
 *
 * Purpose:	Creates a new empty group with the specified name. The name
 *		is either an absolute name or is relative to LOC.
 *
 * Return:	Success:	A handle for the group.	 The group is opened
 *				and should eventually be close by calling
 *				H5G_close().
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Aug 11 1997
 *
 *-------------------------------------------------------------------------
 */
H5G_t *
H5G__create(H5F_t *file, H5G_obj_create_t *gcrt_info, hid_t dxpl_id)
{
    H5G_t	*grp = NULL;	/*new group			*/
    unsigned    oloc_init = 0;  /* Flag to indicate that the group object location was created successfully */
    H5G_t *ret_value = NULL;    /* Return value */

    FUNC_ENTER_PACKAGE

    /* check args */
    HDassert(file);
    HDassert(gcrt_info->gcpl_id != H5P_DEFAULT);
    HDassert(dxpl_id != H5P_DEFAULT);

    /* create an open group */
    if(NULL == (grp = H5FL_CALLOC(H5G_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Create the group object header */
    if(H5G__obj_create(file, dxpl_id, gcrt_info, &(grp->oloc)/*out*/) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header")
    oloc_init = 1;    /* Indicate that the object location information is valid */

    /* Add group to list of open objects in file */
    if(H5FO_top_incr(grp->oloc.file, grp->oloc.addr) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_CANTINC, NULL, "can't incr object ref. count")
    if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared, TRUE) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects")

    /* Set the count of times the object is opened */
    grp->shared->fo_count = 1;

    /* Set return value */
    ret_value = grp;

done:
    if(ret_value == NULL) {
        /* Check if we need to release the file-oriented symbol table info */
        if(oloc_init) {
            if(H5O_dec_rc_by_loc(&(grp->oloc), dxpl_id) < 0)
                HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object")
            if(H5O_close(&(grp->oloc)) < 0)
                HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release object header")
            if(H5O_delete(file, dxpl_id, grp->oloc.addr) < 0)
                HDONE_ERROR(H5E_SYM, H5E_CANTDELETE, NULL, "unable to delete object header")
        } /* end if */
        if(grp != NULL) {
            if(grp->shared != NULL)
                grp->shared = H5FL_FREE(H5G_shared_t, grp->shared);
            grp = H5FL_FREE(H5G_t, grp);
        } /* end if */
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G__create() */
Ejemplo n.º 4
0
/*-------------------------------------------------------------------------
 * Function:	H5O_chunk_protect
 *
 * Purpose:	Protect an object header chunk for modifications
 *
 * Return:	Success:	Non-negative
 *		Failure:	Negative
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Jul 17 2008
 *
 *-------------------------------------------------------------------------
 */
H5O_chunk_proxy_t *
H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
{
    H5O_chunk_proxy_t *chk_proxy = NULL;        /* Proxy for protected chunk */
    H5O_chunk_proxy_t *ret_value;               /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, oh->cache_info.addr, NULL)

    /* check args */
    HDassert(f);
    HDassert(oh);
    HDassert(idx < oh->nchunks);

    /* Check for protecting first chunk */
    if(0 == idx) {
        /* Create new "fake" chunk proxy for first chunk */
        /* (since the first chunk is already handled by the H5O_t object) */
        if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t)))
            HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed")

        /* Increment reference count on object header */
        if(H5O_inc_rc(oh) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")

        /* Set chunk proxy fields */
        chk_proxy->oh = oh;
        chk_proxy->chunkno = idx;
    } /* end if */
    else {
Ejemplo n.º 5
0
/*-------------------------------------------------------------------------
 * Function:    H5O_link_decode
 *
 * Purpose:     Decode a message and return a pointer to
 *              a newly allocated one.
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Quincey Koziol
 *              [email protected]
 *              Aug 29 2005
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5O_link_t          *lnk = NULL;    /* Pointer to link message */
    size_t              len = 0;        /* Length of a string in the message */
    unsigned char       link_flags;     /* Flags for encoding link info */
    void                *ret_value;     /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(f);
    HDassert(p);

    /* decode */
    if(*p++ != H5O_LINK_VERSION)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")

    /* Allocate space for message */
    if(NULL == (lnk = H5FL_CALLOC(H5O_link_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Get the encoding flags for the link */
    link_flags = *p++;
    if(link_flags & ~H5O_LINK_ALL_FLAGS)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message")

    /* Check for non-default link type */
    if(link_flags & H5O_LINK_STORE_LINK_TYPE) {
        /* Get the type of the link */
        lnk->type = (H5L_type_t)*p++;
        if(lnk->type < H5L_TYPE_HARD || lnk->type > H5L_TYPE_MAX)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type")
    } /* end if */
Ejemplo n.º 6
0
/*-------------------------------------------------------------------------
 * 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:	H5A_dense_build_table_cb
 *
 * Purpose:	Callback routine for building table of attributes from dense
 *              attribute storage.
 *
 * Return:	Success:        Non-negative
 *		Failure:	Negative
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Dec 11 2006
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5A_dense_build_table_cb(const H5A_t *attr, void *_udata)
{
    H5A_dense_bt_ud_t *udata = (H5A_dense_bt_ud_t *)_udata;     /* 'User data' passed in */
    herr_t ret_value = H5_ITER_CONT;   /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check arguments */
    HDassert(attr);
    HDassert(udata);
    HDassert(udata->curr_attr < udata->atable->nattrs);

    /* Allocate attribute for entry in the table */
    if(NULL == (udata->atable->attrs[udata->curr_attr] = H5FL_CALLOC(H5A_t)))
        HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, H5_ITER_ERROR, "can't allocate attribute")

    /* Copy attribute information.  Share the attribute object in copying. */
    if(NULL == H5A_copy(udata->atable->attrs[udata->curr_attr], attr))
        HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")

    /* Increment number of attributes stored */
    udata->curr_attr++;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_build_table_cb() */
Ejemplo n.º 8
0
/*-------------------------------------------------------------------------
 * Function:	H5HL_new
 *
 * Purpose:	Create a new local heap object
 *
 * Return:	Success:	non-NULL pointer to new local heap
 *		Failure:	NULL
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Jan  5 2010
 *
 *-------------------------------------------------------------------------
 */
H5HL_t *
H5HL_new(size_t sizeof_size, size_t sizeof_addr, size_t prfx_size)
{
    H5HL_t *heap = NULL;        /* New local heap */
    H5HL_t *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI(H5HL_new, NULL)

    /* check arguments */
    HDassert(sizeof_size > 0);
    HDassert(sizeof_addr > 0);
    HDassert(prfx_size > 0);

    /* Allocate new local heap structure */
    if(NULL == (heap = H5FL_CALLOC(H5HL_t)))
	HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed")

    /* Initialize non-zero fields */
    heap->sizeof_size = sizeof_size;
    heap->sizeof_addr = sizeof_addr;
    heap->prfx_size = prfx_size;

    /* Set the return value */
    ret_value = heap;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HL_new() */
Ejemplo n.º 9
0
/*-------------------------------------------------------------------------
 * Function:	H5HL_dblk_new
 *
 * Purpose:	Create a new local heap data block object
 *
 * Return:	Success:	non-NULL pointer to new local heap data block
 *		Failure:	NULL
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Oct 12 2008
 *
 *-------------------------------------------------------------------------
 */
H5HL_dblk_t *
H5HL_dblk_new(H5HL_t *heap)
{
    H5HL_dblk_t *dblk = NULL;       /* New local heap data block */
    H5HL_dblk_t *ret_value;         /* Return value */

    FUNC_ENTER_NOAPI(H5HL_dblk_new, NULL)

    /* check arguments */
    HDassert(heap);

    /* Allocate new local heap data block */
    if(NULL == (dblk = H5FL_CALLOC(H5HL_dblk_t)))
	HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed")

    /* Increment ref. count on heap data structure */
    if(H5HL_inc_rc(heap) < 0)
	HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment heap ref. count")

    /* Link the heap & the data block */
    dblk->heap = heap;
    heap->dblk = dblk;

    /* Set the return value */
    ret_value = dblk;

done:
    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HL_dblk_new() */
Ejemplo n.º 10
0
/*-------------------------------------------------------------------------
 * Function:    H5O_ginfo_decode
 *
 * Purpose:     Decode a message and return a pointer to
 *              a newly allocated one.
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Quincey Koziol
 *              [email protected]
 *              Aug 30 2005
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_ginfo_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_ginfo_t         *ginfo = NULL;  /* Pointer to group information message */
    unsigned char       flags;          /* Flags for encoding group info */
    void                *ret_value = NULL;      /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(p);

    /* Version of message */
    if(*p++ != H5O_GINFO_VERSION)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")

    /* Allocate space for message */
    if(NULL == (ginfo = H5FL_CALLOC(H5O_ginfo_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Get the flags for the group */
    flags = *p++;
    if(flags & ~H5O_GINFO_ALL_FLAGS)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message")
    ginfo->store_link_phase_change = (flags & H5O_GINFO_STORE_PHASE_CHANGE) ? TRUE : FALSE;
    ginfo->store_est_entry_info = (flags & H5O_GINFO_STORE_EST_ENTRY_INFO) ? TRUE : FALSE;

    /* Get the max. # of links to store compactly & the min. # of links to store densely */
    if(ginfo->store_link_phase_change) {
        UINT16DECODE(p, ginfo->max_compact)
        UINT16DECODE(p, ginfo->min_dense)
    } /* end if */
    else {
        ginfo->max_compact = H5G_CRT_GINFO_MAX_COMPACT;
        ginfo->min_dense = H5G_CRT_GINFO_MIN_DENSE;
    } /* end else */

    /* Get the estimated # of entries & name lengths */
    if(ginfo->store_est_entry_info) {
        UINT16DECODE(p, ginfo->est_num_entries)
        UINT16DECODE(p, ginfo->est_name_len)
    } /* end if */
    else {
        ginfo->est_num_entries = H5G_CRT_GINFO_EST_NUM_ENTRIES;
        ginfo->est_name_len = H5G_CRT_GINFO_EST_NAME_LEN;
    } /* end if */

    /* Set return value */
    ret_value = ginfo;

done:
    if(ret_value == NULL)
        if(ginfo != NULL)
            ginfo = H5FL_FREE(H5O_ginfo_t, ginfo);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_ginfo_decode() */
Ejemplo n.º 11
0
/*-------------------------------------------------------------------------
 * Function:	H5HG_load
 *
 * Purpose:	Loads a global heap collection from disk.
 *
 * Return:	Success:	Ptr to a global heap collection.
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *              Friday, March 27, 1998
 *
 *-------------------------------------------------------------------------
 */
static H5HG_heap_t *
H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
	   void UNUSED * udata2)
{
    H5HG_heap_t	*heap = NULL;
    uint8_t	*p = NULL;
    size_t	nalloc, need;
    size_t      max_idx = 0;            /* The maximum index seen */
    H5HG_heap_t	*ret_value = NULL;      /* Return value */

    FUNC_ENTER_NOAPI(H5HG_load, NULL)

    /* check arguments */
    HDassert(f);
    HDassert(H5F_addr_defined(addr));
    HDassert(!udata1);
    HDassert(!udata2);

    /* Read the initial 4k page */
    if(NULL == (heap = H5FL_CALLOC(H5HG_heap_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    heap->addr = addr;
    if(NULL == (heap->chunk = H5FL_BLK_MALLOC(gheap_chunk, (size_t)H5HG_MINSIZE)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
    if(H5F_block_read(f, H5FD_MEM_GHEAP, addr, (size_t)H5HG_MINSIZE, dxpl_id, heap->chunk) < 0)
	HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection")

    /* Magic number */
    if(HDmemcmp(heap->chunk, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC))
	HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad global heap collection signature")
    p = heap->chunk + H5_SIZEOF_MAGIC;

    /* Version */
    if(H5HG_VERSION != *p++)
	HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap")

    /* Reserved */
    p += 3;

    /* Size */
    H5F_DECODE_LENGTH(f, p, heap->size);
    HDassert(heap->size >= H5HG_MINSIZE);

    /*
     * If we didn't read enough in the first try, then read the rest of the
     * collection now.
     */
    if(heap->size > H5HG_MINSIZE) {
	haddr_t next_addr = addr + (hsize_t)H5HG_MINSIZE;

	if(NULL == (heap->chunk = H5FL_BLK_REALLOC(gheap_chunk, heap->chunk, heap->size)))
	    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
	if(H5F_block_read(f, H5FD_MEM_GHEAP, next_addr, (heap->size - H5HG_MINSIZE), dxpl_id, heap->chunk + H5HG_MINSIZE) < 0)
	    HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection")
    } /* end if */
Ejemplo n.º 12
0
/*-------------------------------------------------------------------------
 * 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);
}
Ejemplo n.º 13
0
/*-------------------------------------------------------------------------
 *
 * Function:    H5C__tag_entry
 *
 * Purpose:     Tags an entry with the provided tag (contained in the API context).
 *              If sanity checking is enabled, this function will perform 
 *              validation that a proper tag is contained within the provided 
 *              data access property list id before application.
 *
 * Return:      FAIL if error is detected, SUCCEED otherwise.
 *
 * Programmer:  Mike McGreevy
 *              January 14, 2010
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5C__tag_entry(H5C_t *cache, H5C_cache_entry_t *entry)
{
    H5C_tag_info_t *tag_info;	/* Points to a tag info struct */
    haddr_t tag;                /* Tag value */
    herr_t ret_value = SUCCEED;  /* Return value */

    FUNC_ENTER_PACKAGE

    /* Assertions */
    HDassert(cache != NULL);
    HDassert(entry != NULL);
    HDassert(cache->magic == H5C__H5C_T_MAGIC);

    /* Get the tag */
    tag = H5CX_get_tag();

    if(cache->ignore_tags) {
        /* if we're ignoring tags, it's because we're running
           tests on internal functions and may not have inserted a tag 
           value into a given API context before creating some metadata. Thus,
           in this case only, if a tag value has not been set, we can
           arbitrarily set it to something for the sake of passing the tests. 
           If the tag value is set, then we'll just let it get assigned without
           additional checking for correctness. */
        if(!H5F_addr_defined(tag))
            tag = H5AC__IGNORE_TAG;
    } /* end if */
#if H5C_DO_TAGGING_SANITY_CHECKS
    else {
        /* Perform some sanity checks to ensure that a correct tag is being applied */
        if(H5C_verify_tag(entry->type->id, tag) < 0)
            HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "tag verification failed")
    } /* end else */
#endif

    /* Search the list of tagged object addresses in the cache */
    tag_info = (H5C_tag_info_t *)H5SL_search(cache->tag_list, &tag);

    /* Check if this is the first entry for this tagged object */
    if(NULL == tag_info) {
        /* Allocate new tag info struct */
        if(NULL == (tag_info = H5FL_CALLOC(H5C_tag_info_t)))
            HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "can't allocate tag info for cache entry")

        /* Set the tag for all entries */
        tag_info->tag = tag;

        /* Insert tag info into skip list */
        if(H5SL_insert(cache->tag_list, tag_info, &(tag_info->tag)) < 0 )
            HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, "can't insert tag info in skip list")
    } /* end if */
    else
Ejemplo n.º 14
0
/*-------------------------------------------------------------------------
 * Function:	H5O_chunk_add
 *
 * Purpose:	Add new chunk for object header to metadata cache
 *
 * Return:	Success:	Non-negative
 *		Failure:	Negative
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Jul 13 2008
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
    unsigned cont_chunkno)
{
    H5O_chunk_proxy_t *chk_proxy = NULL;        /* Proxy for chunk, to mark it dirty in the cache */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, oh->cache_info.addr, FAIL)

    /* check args */
    HDassert(f);
    HDassert(oh);
    HDassert(idx < oh->nchunks);
    HDassert(idx > 0);

    /* Allocate space for the object header data structure */
    if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")

    /* Set the values in the chunk proxy */
    chk_proxy->f = f;
    chk_proxy->oh = oh;
    chk_proxy->chunkno = idx;
    chk_proxy->cont_chunkno = cont_chunkno;

    chk_proxy->fd_parent_addr = HADDR_UNDEF;
    chk_proxy->fd_parent_ptr = NULL;

    /* Increment reference count on object header */
    if(H5O_inc_rc(oh) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "can't increment reference count on object header")

    /* Insert the chunk proxy into the cache */
    if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk")

    chk_proxy = NULL;

done:
    if(ret_value < 0)
        if(chk_proxy)
            chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);

    FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5O_chunk_add() */
Ejemplo n.º 15
0
/*-------------------------------------------------------------------------
 * Function:	H5G_open
 *
 * Purpose:	Opens an existing group.  The group should eventually be
 *		closed by calling H5G_close().
 *
 * Return:	Success:	Ptr to a new group.
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		Monday, January	 5, 1998
 *
 *-------------------------------------------------------------------------
 */
H5G_t *
H5G_open(const H5G_loc_t *loc, hid_t dxpl_id)
{
    H5G_t           *grp = NULL;        /* Group opened */
    H5G_shared_t    *shared_fo;         /* Shared group object */
    H5G_t *ret_value = NULL;            /* Return value */

    FUNC_ENTER_NOAPI(NULL)

    /* Check args */
    HDassert(loc);

    /* Allocate the group structure */
    if(NULL == (grp = H5FL_CALLOC(H5G_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group")

    /* Shallow copy (take ownership) of the group location object */
    if(H5O_loc_copy(&(grp->oloc), loc->oloc, H5_COPY_SHALLOW) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy object location")
    if(H5G_name_copy(&(grp->path), loc->path, H5_COPY_SHALLOW) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy path")

    /* Check if group was already open */
    if((shared_fo = (H5G_shared_t *)H5FO_opened(grp->oloc.file, grp->oloc.addr)) == NULL) {

        /* Clear any errors from H5FO_opened() */
        H5E_clear_stack(NULL);

        /* Open the group object */
        if(H5G_open_oid(grp, dxpl_id) < 0)
            HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found")

        /* Add group to list of open objects in file */
        if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared, FALSE) < 0) {
            grp->shared = H5FL_FREE(H5G_shared_t, grp->shared);
            HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects")
        } /* end if */
Ejemplo n.º 16
0
/*-------------------------------------------------------------------------
 * Function:	H5O_pline_decode
 *
 * Purpose:	Decodes a filter pipeline message.
 *
 * Return:	Success:	Ptr to the native message.
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *              Wednesday, April 15, 1998
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_pline_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 p_size, const uint8_t *p)
{
    H5O_pline_t		*pline = NULL;          /* Pipeline message */
    H5Z_filter_info_t   *filter;                /* Filter to decode */
    size_t		name_length;            /* Length of filter name */
    size_t		i;                      /* Local index variable */
    const uint8_t *p_end = p + p_size - 1;  /* End of the p buffer */
    void		*ret_value = NULL;      /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(p);

    /* Allocate space for I/O pipeline message */
    if(NULL == (pline = H5FL_CALLOC(H5O_pline_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Version */
    pline->version = *p++;
    if(pline->version < H5O_PLINE_VERSION_1 || pline->version > H5O_PLINE_VERSION_LATEST)
        HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "bad version number for filter pipeline message")

    /* Number of filters */
    pline->nused = *p++;
    if(pline->nused > H5Z_MAX_NFILTERS) {

        /* Reset the number of filters used to avoid array traversal in error
         * handling code.
         */
        pline->nused = 0;

        HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter pipeline message has too many filters")
    }
Ejemplo n.º 17
0
/*-------------------------------------------------------------------------
 * Function:	H5O_load
 *
 * Purpose:	Loads an object header from disk.
 *
 * Return:	Success:	Pointer to the new object header.
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Aug  5 1997
 *
 *-------------------------------------------------------------------------
 */
static H5O_t *
H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
	 void UNUSED * _udata2)
{
    H5O_t	*oh = NULL;     /* Object header read in */
    uint8_t     read_buf[H5O_SPEC_READ_SIZE];       /* Buffer for speculative read */
    const uint8_t *p;           /* Pointer into buffer to decode */
    size_t	spec_read_size; /* Size of buffer to speculatively read in */
    size_t	prefix_size;    /* Size of object header prefix */
    unsigned	nmesgs;         /* Total # of messages in this object header */
    unsigned	curmesg = 0;    /* Current message being decoded in object header */
    unsigned    merged_null_msgs = 0;   /* Number of null messages merged together */
    haddr_t	chunk_addr;     /* Address of first chunk */
    size_t	chunk_size;     /* Size of first chunk */
    haddr_t     eoa;		/* Relative end of file address	*/
    H5O_t	*ret_value;     /* Return value */

    FUNC_ENTER_NOAPI(H5O_load, NULL)

    /* check args */
    HDassert(f);
    HDassert(H5F_addr_defined(addr));
    HDassert(!_udata1);
    HDassert(!_udata2);

    /* Make certain we don't speculatively read off the end of the file */
    if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, H5FD_MEM_OHDR)))
        HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to determine file size")

    /* Compute the size of the speculative object header buffer */
    H5_ASSIGN_OVERFLOW(spec_read_size, MIN(eoa - addr, H5O_SPEC_READ_SIZE), /* From: */ hsize_t, /* To: */ size_t);

    /* Attempt to speculatively read both object header prefix and first chunk */
    if(H5F_block_read(f, H5FD_MEM_OHDR, addr, spec_read_size, dxpl_id, read_buf) < 0)
	HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header")
    p = read_buf;

    /* allocate ohdr and init chunk list */
    if(NULL == (oh = H5FL_CALLOC(H5O_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* File-specific, non-stored information */
    oh->sizeof_size = H5F_SIZEOF_SIZE(f);
    oh->sizeof_addr = H5F_SIZEOF_ADDR(f);

    /* Check for magic number */
    /* (indicates version 2 or later) */
    if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
        /* Magic number */
        p += H5_SIZEOF_MAGIC;

        /* Version */
        oh->version = *p++;
        if(H5O_VERSION_2 != oh->version)
            HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number")

        /* Flags */
        oh->flags = *p++;
        if(oh->flags & ~H5O_HDR_ALL_FLAGS)
            HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)")

        /* Number of messages (to allocate initially) */
        nmesgs = 1;

        /* Number of links to object (unless overridden by refcount message) */
        oh->nlink = 1;

        /* Time fields */
        if(oh->flags & H5O_HDR_STORE_TIMES) {
            uint32_t tmp;       /* Temporary value */

            UINT32DECODE(p, tmp);
            oh->atime = (time_t)tmp;
            UINT32DECODE(p, tmp);
            oh->mtime = (time_t)tmp;
            UINT32DECODE(p, tmp);
            oh->ctime = (time_t)tmp;
            UINT32DECODE(p, tmp);
            oh->btime = (time_t)tmp;
        } /* end if */
        else
            oh->atime = oh->mtime = oh->ctime = oh->btime = 0;

        /* Attribute fields */
        if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
            UINT16DECODE(p, oh->max_compact);
            UINT16DECODE(p, oh->min_dense);
            if(oh->max_compact < oh->min_dense)
                HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header attribute phase change values")
        } /* end if */
Ejemplo n.º 18
0
/*-------------------------------------------------------------------------
 * Function:	H5O_pline_decode
 *
 * Purpose:	Decodes a filter pipeline message.
 *
 * Return:	Success:	Ptr to the native message.
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *              Wednesday, April 15, 1998
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_pline_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, const uint8_t *p)
{
    H5O_pline_t		*pline = NULL;          /* Pipeline message */
    H5Z_filter_info_t   *filter;                /* Filter to decode */
    size_t		name_length;            /* Length of filter name */
    size_t		i;                      /* Local index variable */
    void		*ret_value = NULL;      /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check args */
    HDassert(p);

    /* Allocate space for I/O pipeline message */
    if(NULL == (pline = H5FL_CALLOC(H5O_pline_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Version */
    pline->version = *p++;
    if(pline->version < H5O_PLINE_VERSION_1 || pline->version > H5O_PLINE_VERSION_LATEST)
	HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "bad version number for filter pipeline message")

    /* Number of filters */
    pline->nused = *p++;
    if(pline->nused > H5Z_MAX_NFILTERS)
	HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter pipeline message has too many filters")

    /* Reserved */
    if(pline->version == H5O_PLINE_VERSION_1)
        p += 6;

    /* Allocate array for filters */
    pline->nalloc = pline->nused;
    if(NULL == (pline->filter = (H5Z_filter_info_t *)H5MM_calloc(pline->nalloc * sizeof(pline->filter[0]))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Decode filters */
    for(i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) {
        /* Filter ID */
	UINT16DECODE(p, filter->id);

        /* Length of filter name */
        if(pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED)
            name_length = 0;
        else {
            UINT16DECODE(p, name_length);
            if(pline->version == H5O_PLINE_VERSION_1 && name_length % 8)
                HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter name length is not a multiple of eight")
        } /* end if */

        /* Filter flags */
	UINT16DECODE(p, filter->flags);

        /* Number of filter parameters ("client data elements") */
	UINT16DECODE(p, filter->cd_nelmts);

        /* Filter name, if there is one */
	if(name_length) {
            size_t actual_name_length;          /* Actual length of name */

            /* Determine actual name length (without padding, but with null terminator) */
	    actual_name_length = HDstrlen((const char *)p) + 1;
	    HDassert(actual_name_length <= name_length);

            /* Allocate space for the filter name, or use the internal buffer */
            if(actual_name_length > H5Z_COMMON_NAME_LEN) {
                filter->name = (char *)H5MM_malloc(actual_name_length);
                if(NULL == filter->name)
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name")
            } /* end if */
            else
                filter->name = filter->_name;

	    HDstrncpy(filter->name, (const char *)p, actual_name_length);
	    p += name_length;
	} /* end if */
Ejemplo n.º 19
0
/*-------------------------------------------------------------------------
 * Function:    H5O_layout_decode
 *
 * Purpose:     Decode an data layout message and return a pointer to a
 *              new one created with malloc().
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, October  8, 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5O_layout_t           *mesg = NULL;
    unsigned               u;
    void                   *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_layout_decode)

    /* check args */
    HDassert(f);
    HDassert(p);

    /* decode */
    if(NULL == (mesg = H5FL_CALLOC(H5O_layout_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    mesg->version = *p++;
    if(mesg->version < H5O_LAYOUT_VERSION_1 || mesg->version > H5O_LAYOUT_VERSION_3)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message")

    if(mesg->version < H5O_LAYOUT_VERSION_3) {
        unsigned	ndims;			/* Num dimensions in chunk           */

        /* Dimensionality */
        ndims = *p++;
        if(ndims > H5O_LAYOUT_NDIMS)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large")

        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;
        assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);

        /* Reserved bytes */
        p += 5;

        /* Address */
        if(mesg->type == H5D_CONTIGUOUS) {
            H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_CONTIG;
        } /* end if */
        else if(mesg->type == H5D_CHUNKED) {
            H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_CHUNK;

            /* Set the chunk operations */
            /* (Only "btree" indexing type currently supported in this version) */
            mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
            mesg->storage.u.chunk.ops = H5D_COPS_BTREE;
        } /* end if */
        else {
            /* Sanity check */
            HDassert(mesg->type == H5D_COMPACT);

            /* Set the layout operations */
            mesg->ops = H5D_LOPS_COMPACT;
        } /* end else */

        /* Read the size */
        if(mesg->type != H5D_CHUNKED) {
            /* Don't compute size of contiguous storage here, due to possible
             * truncation of the dimension sizes when they were stored in this
             * version of the layout message.  Compute the contiguous storage
             * size in the dataset code, where we've got the dataspace
             * information available also.  - QAK 5/26/04
             */
            p += ndims * 4;     /* Skip over dimension sizes (32-bit quantities) */
        } /* end if */
        else {
            mesg->u.chunk.ndims=ndims;
            for(u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->u.chunk.dim[u]);

            /* Compute chunk size */
            for(u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < ndims; u++)
                mesg->u.chunk.size *= mesg->u.chunk.dim[u];
        } /* end if */

        if(mesg->type == H5D_COMPACT) {
            UINT32DECODE(p, mesg->storage.u.compact.size);
            if(mesg->storage.u.compact.size > 0) {
                if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
                HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
                p += mesg->storage.u.compact.size;
            } /* end if */
        } /* end if */
    } /* end if */
    else {
        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;

        /* Interpret the rest of the message according to the layout class */
        switch(mesg->type) {
            case H5D_COMPACT:
                UINT16DECODE(p, mesg->storage.u.compact.size);
                if(mesg->storage.u.compact.size > 0) {
                    if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size)))
                        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer")
                    HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size);
                    p += mesg->storage.u.compact.size;
                } /* end if */

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_COMPACT;
                break;

            case H5D_CONTIGUOUS:
                H5F_addr_decode(f, &p, &(mesg->storage.u.contig.addr));
                H5F_DECODE_LENGTH(f, p, mesg->storage.u.contig.size);

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_CONTIG;
                break;

            case H5D_CHUNKED:
                /* Dimensionality */
                mesg->u.chunk.ndims = *p++;
                if(mesg->u.chunk.ndims > H5O_LAYOUT_NDIMS)
                    HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large")

                /* B-tree address */
                H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr));

                /* Chunk dimensions */
                for(u = 0; u < mesg->u.chunk.ndims; u++)
                    UINT32DECODE(p, mesg->u.chunk.dim[u]);

                /* Compute chunk size */
                for(u = 1, mesg->u.chunk.size = mesg->u.chunk.dim[0]; u < mesg->u.chunk.ndims; u++)
                    mesg->u.chunk.size *= mesg->u.chunk.dim[u];

                /* Set the chunk operations */
                /* (Only "btree" indexing type supported with v3 of message format) */
                mesg->storage.u.chunk.idx_type = H5D_CHUNK_BTREE;
                mesg->storage.u.chunk.ops = H5D_COPS_BTREE;

                /* Set the layout operations */
                mesg->ops = H5D_LOPS_CHUNK;
                break;

            default:
                HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class")
        } /* end switch */
    } /* end else */

    /* Set return value */
    ret_value = mesg;

done:
    if(ret_value == NULL)
        if(mesg)
            mesg = H5FL_FREE(H5O_layout_t, mesg);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_decode() */
Ejemplo n.º 20
0
/*-------------------------------------------------------------------------
 * Function:	H5F__cache_superblock_deserialize
 *
 * Purpose:	Loads an object from the disk.
 *
 * Return:	Success:	Pointer to new object
 *		Failure:	NULL
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		July 18 2013
 *
 *-------------------------------------------------------------------------
 */
static void *
H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata,
    hbool_t H5_ATTR_UNUSED *dirty)
{
    H5F_super_t         *sblock = NULL; /* File's superblock */
    H5F_superblock_cache_ud_t *udata = (H5F_superblock_cache_ud_t *)_udata; /* User data */
    const uint8_t	*image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
    size_t              variable_size;  /* Sariable size of superblock */
    unsigned            super_vers;     /* Superblock version */
    uint8_t             sizeof_addr;    /* Size of offsets in the file (in bytes) */
    uint8_t             sizeof_size;    /* Size of lengths in the file (in bytes) */
    H5F_super_t         *ret_value;     /* Return value */

    FUNC_ENTER_STATIC

    /* Check arguments */
    HDassert(image);
    HDassert(udata);
    HDassert(udata->f);

    /* Allocate space for the superblock */
    if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Skip over signature (already checked when locating the superblock) */
    image += H5F_SIGNATURE_LEN;

    /* Superblock version */
    super_vers = *image++;
    if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number")

    /* Record the superblock version */
    sblock->super_vers = super_vers;

    /* Sanity check */
    HDassert(((size_t)(image - (const uint8_t *)_image)) == H5F_SUPERBLOCK_FIXED_SIZE);
    HDassert(len >= H5F_SUPERBLOCK_FIXED_SIZE + 6);

    /* Determine the size of addresses & size of offsets, for computing the
     * variable-sized portion of the superblock.
     */
    if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
        sizeof_addr = image[4];
        sizeof_size = image[5];
    } /* end if */
    else {
        sizeof_addr = image[0];
        sizeof_size = image[1];
    } /* end else */
    if(sizeof_addr != 2 && sizeof_addr != 4 &&
            sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
    if(sizeof_size != 2 && sizeof_size != 4 &&
            sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
    sblock->sizeof_addr = sizeof_addr;
    sblock->sizeof_size = sizeof_size;

    /* Determine the size of the variable-length part of the superblock */
    variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, sizeof_addr, sizeof_size);
    HDassert(variable_size > 0);

    /* Handle metadata cache retry for variable-sized portion of the superblock */
    if(len != (H5F_SUPERBLOCK_FIXED_SIZE + variable_size)) {
        /* Sanity check */
        HDassert(len == (H5F_SUPERBLOCK_FIXED_SIZE + H5F_SUPERBLOCK_MINIMAL_VARLEN_SIZE));

        /* Make certain we can read the variabled-sized portion of the superblock */
        if(H5F__set_eoa(udata->f, H5FD_MEM_SUPER, (haddr_t)(H5F_SUPERBLOCK_FIXED_SIZE + variable_size)) < 0)
            HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
    } /* end if */
Ejemplo n.º 21
0
/*-------------------------------------------------------------------------
 * Function:	H5F__cache_superblock_deserialize
 *
 * Purpose:	Loads an object from the disk.
 *
 * Return:	Success:	Pointer to new object
 *		Failure:	NULL
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		July 18 2013
 *
 *-------------------------------------------------------------------------
 */
static void *
H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata,
    hbool_t H5_ATTR_UNUSED *dirty)
{
    H5F_super_t         *sblock = NULL; /* File's superblock */
    H5F_superblock_cache_ud_t *udata = (H5F_superblock_cache_ud_t *)_udata; /* User data */
    const uint8_t	*image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
    size_t              variable_size;  /* Variable size of superblock */
    unsigned            super_vers;     /* Superblock version */
    uint8_t             sizeof_addr;    /* Size of offsets in the file (in bytes) */
    uint8_t             sizeof_size;    /* Size of lengths in the file (in bytes) */
    H5F_super_t         *ret_value = NULL;      /* Return value */

    FUNC_ENTER_STATIC

    /* Check arguments */
    HDassert(image);
    HDassert(udata);
    HDassert(udata->f);

    /* Allocate space for the superblock */
    if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    image += H5F_SIGNATURE_LEN;

    /* Superblock version */
    super_vers = *image++;
    if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number")

    /* Record the superblock version */
    sblock->super_vers = super_vers;

    /* Sanity check */
    HDassert(((size_t)(image - (const uint8_t *)_image)) == H5F_SUPERBLOCK_FIXED_SIZE);
    HDassert(len >= H5F_SUPERBLOCK_FIXED_SIZE + 6);

    /* Determine the size of addresses & size of offsets, for computing the
     * variable-sized portion of the superblock.
     */
    if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
        sizeof_addr = image[4];
        sizeof_size = image[5];
    } /* end if */
    else {
        sizeof_addr = image[0];
        sizeof_size = image[1];
    } /* end else */
    if(sizeof_addr != 2 && sizeof_addr != 4 &&
            sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
    if(sizeof_size != 2 && sizeof_size != 4 &&
            sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
    sblock->sizeof_addr = sizeof_addr;
    sblock->sizeof_size = sizeof_size;

    /* Determine the size of the variable-length part of the superblock */
    variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, sizeof_addr, sizeof_size);
    HDassert(variable_size > 0);

    HDassert(len == (H5F_SUPERBLOCK_FIXED_SIZE + variable_size));

    /* Check for older version of superblock format */
    if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
	uint32_t    status_flags;	    /* File status flags	   */
	unsigned    sym_leaf_k;         /* Symbol table leaf node's 'K' value */
	unsigned    snode_btree_k;      /* B-tree symbol table internal node 'K' value */
	unsigned    chunk_btree_k;      /* B-tree chunk internal node 'K' value */

	/* Freespace version (hard-wired) */
	if(HDF5_FREESPACE_VERSION != *image++)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number")

	/* Root group version number (hard-wired) */
	if(HDF5_OBJECTDIR_VERSION != *image++)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number")

	/* Skip over reserved byte */
	image++;

	/* Shared header version number (hard-wired) */
	if(HDF5_SHAREDHEADER_VERSION != *image++)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number")

	/* Size of file addresses */
	sizeof_addr = *image++;
	if(sizeof_addr != 2 && sizeof_addr != 4 &&
		sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
	sblock->sizeof_addr = sizeof_addr;
	udata->f->shared->sizeof_addr = sizeof_addr;  /* Keep a local copy also */

	/* Size of file sizes */
	sizeof_size = *image++;
	if(sizeof_size != 2 && sizeof_size != 4 &&
		sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
	sblock->sizeof_size = sizeof_size;
	udata->f->shared->sizeof_size = sizeof_size;  /* Keep a local copy also */

	/* Skip over reserved byte */
	image++;

	/* Various B-tree sizes */
	UINT16DECODE(image, sym_leaf_k);
	if(sym_leaf_k == 0)
	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank")
        udata->sym_leaf_k = sym_leaf_k;    /* Keep a local copy also */

        /* Need 'get' call to set other array values */
        UINT16DECODE(image, snode_btree_k);
        if(snode_btree_k == 0)
	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes")
	udata->btree_k[H5B_SNODE_ID] = snode_btree_k;

	/*
         * Delay setting the value in the property list until we've checked
         * for the indexed storage B-tree internal 'K' value later.
         */

        /* File status flags (not really used yet) */
        UINT32DECODE(image, status_flags);
        HDassert(status_flags <= 255);
        sblock->status_flags = (uint8_t)status_flags;
        if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")

	/*
         * If the superblock version # is greater than 0, read in the indexed
         * storage B-tree internal 'K' value
         */
        if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
	    UINT16DECODE(image, chunk_btree_k);

	    /* Reserved bytes are present only in version 1 */
	    if(super_vers == HDF5_SUPERBLOCK_VERSION_1)
		image += 2;   /* reserved */
	} /* end if */
	else
	    chunk_btree_k = HDF5_BTREE_CHUNK_IK_DEF;
	udata->btree_k[H5B_CHUNK_ID] = chunk_btree_k;

	/* Remainder of "variable-sized" portion of superblock */
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr/*out*/);
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr/*out*/);
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &udata->stored_eof/*out*/);
	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->driver_addr/*out*/);

	/* Allocate space for the root group symbol table entry */
	HDassert(!sblock->root_ent);
	if(NULL == (sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t))))
	    HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for root group symbol table entry")

	/* decode the root group symbol table entry */
	if(H5G_ent_decode(udata->f, (const uint8_t **)&image, sblock->root_ent) < 0)
	    HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry")

	/* Set the root group address to the correct value */
	sblock->root_addr = sblock->root_ent->header;

	/* This step is for h5repart tool only. If user wants to change file driver
         *  from family to sec2 while using h5repart, set the driver address to
         *  undefined to let the library ignore the family driver information saved
         *  in the superblock.
         */
	if(udata->ignore_drvrinfo && H5F_addr_defined(sblock->driver_addr)) {
	    /* Eliminate the driver info */
	    sblock->driver_addr = HADDR_UNDEF;
            udata->drvrinfo_removed = TRUE;
	} /* end if */

	/* NOTE: Driver info block is decoded separately, later */

    } /* end if */
Ejemplo n.º 22
0
/*-------------------------------------------------------------------------
 * Function:    H5F_sblock_load
 *
 * Purpose:     Loads the superblock from the file, and deserializes
 *              its information into the H5F_super_t structure.
 *
 * Return:      Success:        SUCCEED
 *              Failure:        NULL
 *
 * Programmer:  Mike McGreevy
 *              [email protected]
 *              April 8, 2009
 *
 *-------------------------------------------------------------------------
 */
static H5F_super_t *
H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata)
{
    H5F_super_t        *sblock = NULL;      /* File's superblock */
    haddr_t             base_addr = HADDR_UNDEF;        /* Base address of file */
    uint8_t             sbuf[H5F_MAX_SUPERBLOCK_SIZE];     /* Buffer for superblock */
    H5P_genplist_t     *dxpl;               /* DXPL object */
    H5P_genplist_t     *c_plist;            /* File creation property list  */
    H5F_file_t         *shared;             /* shared part of `file'        */
    H5FD_t             *lf;                 /* file driver part of `shared' */
    haddr_t             stored_eoa;         /*relative end-of-addr in file  */
    haddr_t             eof;                /*end of file address           */
    uint8_t             sizeof_addr;        /* Size of offsets in the file (in bytes) */
    uint8_t             sizeof_size;        /* Size of lengths in the file (in bytes) */
    const size_t        fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock   */
    size_t              variable_size;      /*variable sizeof superblock    */
    uint8_t            *p;                  /* Temporary pointer into encoding buffer */
    unsigned            super_vers;         /* Superblock version          */
    hbool_t            *dirtied = (hbool_t *)_udata;  /* Set up dirtied out value */
    H5F_super_t        *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

    /* check arguments */
    HDassert(f);
    HDassert(H5F_addr_eq(addr, 0));
    HDassert(dirtied);

    /* Short cuts */
    shared = f->shared;
    lf = shared->lf;

    /* Get the shared file creation property list */
    if(NULL == (c_plist = (H5P_genplist_t *)H5I_object(shared->fcpl_id)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list")

    /* Get the base address for the file in the VFD */
    if(HADDR_UNDEF == (base_addr = H5FD_get_base_addr(lf)))
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "failed to get base address for file driver")

    /* Allocate space for the superblock */
    if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Get the DXPL plist object for DXPL ID */
    if(NULL == (dxpl = (H5P_genplist_t *)H5I_object(dxpl_id)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list")

    /* Read fixed-size portion of the superblock */
    p = sbuf;
    H5_CHECK_OVERFLOW(fixed_size, size_t, haddr_t);
    if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)fixed_size) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
    if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, (haddr_t)0, fixed_size, p) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")

    /* Skip over signature (already checked when locating the superblock) */
    p += H5F_SIGNATURE_LEN;

    /* Superblock version */
    super_vers = *p++;
    if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number")
    if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version")

    /* Record the superblock version */
    sblock->super_vers = super_vers;

    /* Sanity check */
    HDassert(((size_t)(p - sbuf)) == fixed_size);

    /* Determine the size of the variable-length part of the superblock */
    variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f);
    HDassert(variable_size > 0);
    HDassert(fixed_size + variable_size <= sizeof(sbuf));

    /* Read in variable-sized portion of superblock */
    if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)(fixed_size + variable_size)) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
    if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, (haddr_t)fixed_size, variable_size, p) < 0)
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock")

    /* Check for older version of superblock format */
    if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
        uint32_t	status_flags;	    /* File status flags	   */
        unsigned        btree_k[H5B_NUM_BTREE_ID];  /* B-tree internal node 'K' values */
        unsigned        sym_leaf_k;         /* Symbol table leaf node's 'K' value */

        /* Freespace version (hard-wired) */
        if(HDF5_FREESPACE_VERSION != *p++)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number")

        /* Root group version number (hard-wired) */
        if(HDF5_OBJECTDIR_VERSION != *p++)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number")

        /* Skip over reserved byte */
        p++;

        /* Shared header version number (hard-wired) */
        if(HDF5_SHAREDHEADER_VERSION != *p++)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number")

        /* Size of file addresses */
        sizeof_addr = *p++;
        if(sizeof_addr != 2 && sizeof_addr != 4 &&
                sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
        if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address")
        shared->sizeof_addr = sizeof_addr;  /* Keep a local copy also */

        /* Size of file sizes */
        sizeof_size = *p++;
        if(sizeof_size != 2 && sizeof_size != 4 &&
                sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size")
        if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size")
        shared->sizeof_size = sizeof_size;  /* Keep a local copy also */

        /* Skip over reserved byte */
        p++;

        /* Various B-tree sizes */
        UINT16DECODE(p, sym_leaf_k);
        if(sym_leaf_k == 0)
            HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank")
        if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes")
        sblock->sym_leaf_k = sym_leaf_k;    /* Keep a local copy also */

        /* Need 'get' call to set other array values */
        if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes")
        UINT16DECODE(p, btree_k[H5B_SNODE_ID]);
        if(btree_k[H5B_SNODE_ID] == 0)
            HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes")
        /*
         * Delay setting the value in the property list until we've checked
         * for the indexed storage B-tree internal 'K' value later.
         */

        /* File status flags (not really used yet) */
        UINT32DECODE(p, status_flags);
        HDassert(status_flags <= 255);
        sblock->status_flags = (uint8_t)status_flags;
        if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
            HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")

        /*
         * If the superblock version # is greater than 0, read in the indexed
         * storage B-tree internal 'K' value
         */
        if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
            UINT16DECODE(p, btree_k[H5B_CHUNK_ID]);
            /* Reserved bytes are present only in version 1 */
            if(super_vers == HDF5_SUPERBLOCK_VERSION_1)
                p += 2;   /* reserved */
        } /* end if */
        else
            btree_k[H5B_CHUNK_ID] = HDF5_BTREE_CHUNK_IK_DEF;

        /* Set the B-tree internal node values, etc */
        if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0)
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for btree internal nodes")
        HDmemcpy(sblock->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID);    /* Keep a local copy also */

        /* Remainder of "variable-sized" portion of superblock */
        H5F_addr_decode(f, (const uint8_t **)&p, &sblock->base_addr/*out*/);
        H5F_addr_decode(f, (const uint8_t **)&p, &sblock->ext_addr/*out*/);
        H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
        H5F_addr_decode(f, (const uint8_t **)&p, &sblock->driver_addr/*out*/);

        /* Allocate space for the root group symbol table entry */
        HDassert(!sblock->root_ent);
        if(NULL == (sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t))))
            HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for root group symbol table entry")

        /* decode the root group symbol table entry */
        if(H5G_ent_decode(f, (const uint8_t **)&p, sblock->root_ent) < 0)
            HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry")

        /* Set the root group address to the correct value */
        sblock->root_addr = sblock->root_ent->header;

        /*
         * Check if superblock address is different from base address and
         * adjust base address and "end of address" address if so.
         */
        if(!H5F_addr_eq(base_addr, sblock->base_addr)) {
            /* Check if the superblock moved earlier in the file */
            if(H5F_addr_lt(base_addr, sblock->base_addr))
                stored_eoa -= (sblock->base_addr - base_addr);
            else
                /* The superblock moved later in the file */
                stored_eoa += (base_addr - sblock->base_addr);

            /* Adjust base address for offsets of the HDF5 data in the file */
            sblock->base_addr = base_addr;

            /* Set the base address for the file in the VFD now */
            if(H5FD_set_base_addr(lf, sblock->base_addr) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "failed to set base address for file driver")

            /* Indicate that the superblock should be marked dirty */
            *dirtied = TRUE;
        } /* end if */

        /* This step is for h5repart tool only. If user wants to change file driver
         *  from family to sec2 while using h5repart, set the driver address to
         *  undefined to let the library ignore the family driver information saved
         *  in the superblock.
         */
        if(H5F_HAS_FEATURE(f, H5FD_FEAT_IGNORE_DRVRINFO)) {
            /* Eliminate the driver info */
            sblock->driver_addr = HADDR_UNDEF;

            /* Indicate that the superblock should be marked dirty */
            *dirtied = TRUE;
        } /* end if */

        /* Decode the optional driver information block */
        if(H5F_addr_defined(sblock->driver_addr)) {
            uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE];     /* Buffer for driver info block */
            char drv_name[9];       /* Name of driver */
            unsigned drv_vers;      /* Version of driver info block */
            size_t drv_variable_size; /* Size of variable-length portion of driver info block, in bytes */

            /* Read in fixed-sized portion of driver info block */
            p = dbuf;
            if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
            if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, sblock->driver_addr, (size_t)H5F_DRVINFOBLOCK_HDR_SIZE, p) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read driver information block")

            /* Version number */
            drv_vers = *p++;
            if(drv_vers != HDF5_DRIVERINFO_VERSION_0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad driver information block version number")

            p += 3; /* reserved bytes */

            /* Driver info size */
            UINT32DECODE(p, drv_variable_size);

            /* Sanity check */
            HDassert(H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size <= sizeof(dbuf));

            /* Driver name and/or version */
            HDstrncpy(drv_name, (const char *)p, (size_t)8);
            drv_name[8] = '\0';
            p += 8; /* advance past name/version */

            /* Check if driver matches driver information saved. Unfortunately, we can't push this
             * function to each specific driver because we're checking if the driver is correct.
             */
            if(!HDstrncmp(drv_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family"))
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "family driver should be used")
            if(!HDstrncmp(drv_name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi"))
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "multi driver should be used")

            /* Read in variable-sized portion of driver info block */
            if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
            if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE, drv_variable_size, p) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file driver information")

            /* Decode driver information */
            if(H5FD_sb_decode(lf, drv_name, p) < 0)
                HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to decode driver information")
        } /* end if */
Ejemplo n.º 23
0
/*--------------------------------------------------------------------------
 NAME
    H5O_sdspace_decode
 PURPOSE
    Decode a simple dimensionality message and return a pointer to a memory
	struct with the decoded information
 USAGE
    void *H5O_sdspace_decode(f, dxpl_id, mesg_flags, p)
	H5F_t *f;	        IN: pointer to the HDF5 file struct
        hid_t dxpl_id;          IN: DXPL for any I/O
        unsigned mesg_flags;    IN: Message flags to influence decoding
	const uint8 *p;		IN: the raw information buffer
 RETURNS
    Pointer to the new message in native order on success, NULL on failure
 DESCRIPTION
	This function decodes the "raw" disk form of a simple dimensionality
    message into a struct in memory native format.  The struct is allocated
    within this function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5S_extent_t	*sdim = NULL;/* New extent dimensionality structure */
    void		*ret_value;
    unsigned		i;		/* local counting variable */
    unsigned		flags, version;

    FUNC_ENTER_NOAPI_NOINIT(H5O_sdspace_decode)

    /* check args */
    HDassert(f);
    HDassert(p);

    /* decode */
    if(NULL == (sdim = H5FL_CALLOC(H5S_extent_t)))
        HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, NULL, "dataspace structure allocation failed")

    /* Check version */
    version = *p++;
    if(version < H5O_SDSPACE_VERSION_1 || version > H5O_SDSPACE_VERSION_2)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "wrong version number in dataspace message")
    sdim->version = version;

    /* Get rank */
    sdim->rank = *p++;
    if(sdim->rank > H5S_MAX_RANK)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "simple dataspace dimensionality is too large")

    /* Get dataspace flags for later */
    flags = *p++;

    /* Get or determine the type of the extent */
    if(version >= H5O_SDSPACE_VERSION_2)
        sdim->type = (H5S_class_t)*p++;
    else {
        /* Set the dataspace type to be simple or scalar as appropriate */
        if(sdim->rank > 0)
            sdim->type = H5S_SIMPLE;
        else
            sdim->type = H5S_SCALAR;

        /* Increment past reserved byte */
        p++;
    } /* end else */
    HDassert(sdim->type != H5S_NULL || sdim->version >= H5O_SDSPACE_VERSION_2);

    /* Only Version 1 has these reserved bytes */
    if(version == H5O_SDSPACE_VERSION_1)
        p += 4; /*reserved*/

    /* Decode dimension sizes */
    if(sdim->rank > 0) {
        if(NULL == (sdim->size = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)sdim->rank)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

        for(i = 0; i < sdim->rank; i++)
            H5F_DECODE_LENGTH(f, p, sdim->size[i]);

        if(flags & H5S_VALID_MAX) {
            if(NULL == (sdim->max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)sdim->rank)))
                HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
            for(i = 0; i < sdim->rank; i++)
                H5F_DECODE_LENGTH (f, p, sdim->max[i]);
        } /* end if */
    } /* end if */

    /* Compute the number of elements in the extent */
    if(sdim->type == H5S_NULL)
        sdim->nelem = 0;
    else {
        for(i = 0, sdim->nelem = 1; i < sdim->rank; i++)
            sdim->nelem *= sdim->size[i];
    } /* end else */

    /* Set return value */
    ret_value = (void*)sdim;	/*success*/

done:
    if(!ret_value && sdim) {
        H5S_extent_release(sdim);
        sdim = H5FL_FREE(H5S_extent_t, sdim);
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_sdspace_decode() */
Ejemplo n.º 24
0
/*-------------------------------------------------------------------------
 * Function:    H5O_layout_decode
 *
 * Purpose:     Decode an data layout message and return a pointer to a
 *              new one created with malloc().
 *
 * Return:      Success:        Ptr to new message in native order.
 *
 *              Failure:        NULL
 *
 * Programmer:  Robb Matzke
 *              Wednesday, October  8, 1997
 *
 * Modifications:
 * 	Robb Matzke, 1998-07-20
 *	Rearranged the message to add a version number at the beginning.
 *
 *      Raymond Lu, 2002-2-26
 *      Added version number 2 case depends on if space has been allocated
 *      at the moment when layout header message is updated.
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
    H5O_layout_t           *mesg = NULL;
    unsigned               u;
    void                   *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_layout_decode);

    /* check args */
    assert(f);
    assert(p);

    /* decode */
    if (NULL==(mesg = H5FL_CALLOC(H5O_layout_t)))
        HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");

    /* Version. 1 when space allocated; 2 when space allocation is delayed */
    mesg->version = *p++;
    if (mesg->version<H5O_LAYOUT_VERSION_1 || mesg->version>H5O_LAYOUT_VERSION_3)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for layout message");

    if(mesg->version < H5O_LAYOUT_VERSION_3) {
        unsigned	ndims;			/* Num dimensions in chunk           */

        /* Dimensionality */
        ndims = *p++;
        if (ndims>H5O_LAYOUT_NDIMS)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");

        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;
        assert(H5D_CONTIGUOUS == mesg->type || H5D_CHUNKED == mesg->type || H5D_COMPACT == mesg->type);

        /* Reserved bytes */
        p += 5;

        /* Address */
        if(mesg->type==H5D_CONTIGUOUS)
            H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
        else if(mesg->type==H5D_CHUNKED)
            H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));

        /* Read the size */
        if(mesg->type!=H5D_CHUNKED) {
	    mesg->unused.ndims=ndims;

            for (u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->unused.dim[u]);

            /* Don't compute size of contiguous storage here, due to possible
             * truncation of the dimension sizes when they were stored in this
             * version of the layout message.  Compute the contiguous storage
             * size in the dataset code, where we've got the dataspace
             * information available also.  - QAK 5/26/04
             */
        } /* end if */
        else {
            mesg->u.chunk.ndims=ndims;
            for (u = 0; u < ndims; u++)
                UINT32DECODE(p, mesg->u.chunk.dim[u]);

            /* Compute chunk size */
            for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<ndims; u++)
                mesg->u.chunk.size *= mesg->u.chunk.dim[u];
        } /* end if */

        if(mesg->type == H5D_COMPACT) {
            UINT32DECODE(p, mesg->u.compact.size);
            if(mesg->u.compact.size > 0) {
                if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
                    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
                HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
                p += mesg->u.compact.size;
            }
        }
    } /* end if */
    else {
        /* Layout class */
        mesg->type = (H5D_layout_t)*p++;

        /* Interpret the rest of the message according to the layout class */
        switch(mesg->type) {
            case H5D_CONTIGUOUS:
                H5F_addr_decode(f, &p, &(mesg->u.contig.addr));
                H5F_DECODE_LENGTH(f, p, mesg->u.contig.size);
                break;

            case H5D_CHUNKED:
                /* Dimensionality */
                mesg->u.chunk.ndims = *p++;
                if (mesg->u.chunk.ndims>H5O_LAYOUT_NDIMS)
                    HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large");

                /* B-tree address */
                H5F_addr_decode(f, &p, &(mesg->u.chunk.addr));

                /* Chunk dimensions */
                for (u = 0; u < mesg->u.chunk.ndims; u++)
                    UINT32DECODE(p, mesg->u.chunk.dim[u]);

                /* Compute chunk size */
                for (u=1, mesg->u.chunk.size=mesg->u.chunk.dim[0]; u<mesg->u.chunk.ndims; u++)
                    mesg->u.chunk.size *= mesg->u.chunk.dim[u];
                break;

            case H5D_COMPACT:
                UINT16DECODE(p, mesg->u.compact.size);
                if(mesg->u.compact.size > 0) {
                    if(NULL==(mesg->u.compact.buf=H5MM_malloc(mesg->u.compact.size)))
                        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer");
                    HDmemcpy(mesg->u.compact.buf, p, mesg->u.compact.size);
                    p += mesg->u.compact.size;
                } /* end if */
                break;

            default:
                HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class");
        } /* end switch */
    } /* end else */

    /* Set return value */
    ret_value=mesg;

done:
    if(ret_value==NULL) {
        if(mesg)
            H5FL_FREE(H5O_layout_t,mesg);
    } /* end if */
    FUNC_LEAVE_NOAPI(ret_value);
}
Ejemplo n.º 25
0
/*--------------------------------------------------------------------------
 NAME
    H5O_attr_decode
 PURPOSE
    Decode a attribute message and return a pointer to a memory struct
        with the decoded information
 USAGE
    void *H5O_attr_decode(f, raw_size, p)
        H5F_t *f;               IN: pointer to the HDF5 file struct
        size_t raw_size;        IN: size of the raw information buffer
        const uint8_t *p;         IN: the raw information buffer
 RETURNS
    Pointer to the new message in native order on success, NULL on failure
 DESCRIPTION
        This function decodes the "raw" disk form of a attribute message
    into a struct in memory native format.  The struct is allocated within this
    function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p)
{
    H5A_t		*attr = NULL;
    H5S_extent_t	*extent;	/*extent dimensionality information  */
    size_t		name_len;   	/*attribute name length */
    int		        version;	/*message version number*/
    unsigned            flags = 0;        /* Attribute flags */
    H5A_t		*ret_value;     /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_attr_decode);

    /* check args */
    HDassert(f);
    HDassert(p);

    if(NULL == (attr = H5FL_CALLOC(H5A_t)))
	HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");

    /* Version number */
    version = *p++;
    if (version!=H5O_ATTR_VERSION && version!=H5O_ATTR_VERSION_NEW)
	HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for attribute message");

    /* Get the flags byte if we have a later version of the attribute */
    if(version>H5O_ATTR_VERSION)
        flags = *p++;
    else
        p++;    /* Byte is unused when version<2 */

    /*
     * Decode the sizes of the parts of the attribute.  The sizes stored in
     * the file are exact but the parts are aligned on 8-byte boundaries.
     */
    UINT16DECODE(p, name_len); /*including null*/
    UINT16DECODE(p, attr->dt_size);
    UINT16DECODE(p, attr->ds_size);

    /* Decode and store the name */
    if (NULL==(attr->name=H5MM_strdup((const char *)p)))
	HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
    if(version < H5O_ATTR_VERSION_NEW)
        p += H5O_ALIGN(name_len);    /* advance the memory pointer */
    else
        p += name_len;    /* advance the memory pointer */

    /* decode the attribute datatype */
    if (flags & H5O_ATTR_FLAG_TYPE_SHARED) {
	H5O_shared_t *shared;   /* Shared information */

        /* Get the shared information */
	if (NULL == (shared = (H5O_MSG_SHARED->decode) (f, dxpl_id, p)))
	    HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message");

        /* Get the actual datatype information */
        if((attr->dt= H5O_shared_read(f, dxpl_id, shared, H5O_MSG_DTYPE, NULL))==NULL)
            HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype");

        /* Free the shared information */
        H5O_free_real(H5O_MSG_SHARED, shared);
    } /* end if */
    else {
        if((attr->dt=(H5O_MSG_DTYPE->decode)(f,dxpl_id,p))==NULL)
            HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype");
    } /* end else */
    if(version < H5O_ATTR_VERSION_NEW)
        p += H5O_ALIGN(attr->dt_size);
    else
        p += attr->dt_size;

    /* decode the attribute dataspace */
    if (NULL==(attr->ds = H5FL_CALLOC(H5S_t)))
	HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");

    if((extent=(H5O_MSG_SDSPACE->decode)(f,dxpl_id,p))==NULL)
        HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace");

    /* Copy the extent information */
    HDmemcpy(&(attr->ds->extent),extent, sizeof(H5S_extent_t));

    /* Release temporary extent information */
    H5FL_FREE(H5S_extent_t,extent);

    /* Default to entire dataspace being selected */
    if(H5S_select_all(attr->ds, 0) < 0)
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")

    if(version < H5O_ATTR_VERSION_NEW)
        p += H5O_ALIGN(attr->ds_size);
    else
        p += attr->ds_size;

    /* Compute the size of the data */
    H5_ASSIGN_OVERFLOW(attr->data_size,H5S_GET_EXTENT_NPOINTS(attr->ds)*H5T_get_size(attr->dt),hsize_t,size_t);

    /* Go get the data */
    if(attr->data_size) {
        if (NULL==(attr->data = H5FL_BLK_MALLOC(attr_buf, attr->data_size)))
            HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
        HDmemcpy(attr->data,p,attr->data_size);
    }

    /* Indicate that the fill values aren't to be written out */
    attr->initialized=1;

    /* Set return value */
    ret_value = attr;

done:
    if(!ret_value)
        if(attr) {
            /* Free dynamicly allocated items */
            if(H5A_free(attr) < 0)
                HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't release attribute info")

            H5FL_FREE(H5A_t, attr);
        } /* end if */

    FUNC_LEAVE_NOAPI(ret_value);
}
Ejemplo n.º 26
0
/*-------------------------------------------------------------------------
 * Function:	H5B2__create_leaf
 *
 * Purpose:	Creates empty leaf node of a B-tree and update node pointer
 *              to point to it.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Feb  2 2005
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5B2__create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, void *parent, H5B2_node_ptr_t *node_ptr)
{
    H5B2_leaf_t *leaf = NULL;           /* Pointer to new leaf node created */
    hbool_t inserted = FALSE;           /* Whether the leaf node was inserted into cache */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_PACKAGE

    /* Check arguments. */
    HDassert(hdr);
    HDassert(node_ptr);

    /* Allocate memory for leaf information */
    if(NULL == (leaf = H5FL_CALLOC(H5B2_leaf_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf info")

    /* Increment ref. count on B-tree header */
    if(H5B2__hdr_incr(hdr) < 0)
        HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, FAIL, "can't increment ref. count on B-tree header")

    /* Share B-tree header information */
    leaf->hdr = hdr;

    /* Allocate space for the native keys in memory */
    if(NULL == (leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[0].nat_rec_fac)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf native keys")
    HDmemset(leaf->leaf_native, 0, hdr->cls->nrec_size * hdr->node_info[0].max_nrec);

    /* Set parent */
    leaf->parent = parent;

    /* Set shadowed epoch to header's epoch */
    leaf->shadow_epoch = hdr->shadow_epoch;

    /* Allocate space on disk for the leaf */
    if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(hdr->f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)hdr->node_size)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree leaf node")

    /* Cache the new B-tree node */
    if(H5AC_insert_entry(hdr->f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0)
        HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree leaf to cache")
    inserted = TRUE;

    /* Add leaf node as child of 'top' proxy */
    if(hdr->top_proxy) {
        if(H5AC_proxy_entry_add_child(hdr->top_proxy, hdr->f, dxpl_id, leaf) < 0)
            HGOTO_ERROR(H5E_BTREE, H5E_CANTSET, FAIL, "unable to add v2 B-tree node as child of proxy")
        leaf->top_proxy = hdr->top_proxy;
    } /* end if */

done:
    if(ret_value < 0) {
        if(leaf) {
            /* Remove from cache, if inserted */
            if(inserted)
                if(H5AC_remove_entry(leaf) < 0)
                    HDONE_ERROR(H5E_BTREE, H5E_CANTREMOVE, FAIL, "unable to remove v2 B-tree leaf node from cache")

            /* Release leaf node's disk space */
            if(H5F_addr_defined(node_ptr->addr) && H5MF_xfree(hdr->f, H5FD_MEM_BTREE, dxpl_id, node_ptr->addr, (hsize_t)hdr->node_size) < 0)
                HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release file space for v2 B-tree leaf node")

            /* Destroy leaf node */
            if(H5B2__leaf_free(leaf) < 0)
                HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree leaf node")
        } /* end if */
    } /* end if */

    FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2__create_leaf() */