/*-------------------------------------------------------------------------
 * 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 */
Exemple #2
0
/****************************************************************
**
**  test_refstr_own(): Test basic H5RS (ref-counted strings) code.
**      Tests transferring ownership of dynamically allocated strings
**      to ref-counted strings.
**
****************************************************************/
static void
test_refstr_own(void)
{
    H5RS_str_t *rs;     /* Ref-counted string created */
    char *s;            /* Pointer to string to transfer */
    const char *t;      /* Temporary pointers to string */
    int cmp;            /* Comparison value */
    herr_t ret;         /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Transferring Ref-Counted Strings\n"));

    /* Initialize buffer */
    s = (char *)H5FL_BLK_MALLOC(str_buf,HDstrlen("foo") + 1);
    CHECK(s, NULL, "H5FL_BLK_MALLOC");
    HDstrcpy(s, "foo");

    /* Transfer ownership of dynamically allocated string to ref-counted string */
    rs=H5RS_own(s);
    CHECK(rs, NULL, "H5RS_own");

    /* Get pointer to raw string in ref-counted string */
    t=H5RS_get_str(rs);
    CHECK(t, NULL, "H5RS_get_str");
    VERIFY(t, s, "transferring");
    cmp=HDstrcmp(s,t);
    VERIFY(cmp, 0, "HDstrcmp");

    /* Increment reference count (should NOT duplicate string) */
    ret=H5RS_incr(rs);
    CHECK(ret, FAIL, "H5RS_incr");

    /* Change the buffer initially wrapped */
    *s='F';

    /* Get pointer to raw string in ref-counted string */
    t=H5RS_get_str(rs);
    CHECK(t, NULL, "H5RS_get_str");
    VERIFY(t, s, "transferring");
    cmp=HDstrcmp(t,s);
    VERIFY(cmp, 0, "HDstrcmp");

    /* Decrement reference count for string */
    ret=H5RS_decr(rs);
    CHECK(ret, FAIL, "H5RS_decr");
    ret=H5RS_decr(rs);
    CHECK(ret, FAIL, "H5RS_decr");

} /* end test_refstr_own() */
Exemple #3
0
/*-------------------------------------------------------------------------
 * Function:	H5HF_man_dblock_create
 *
 * Purpose:	Allocate & initialize a managed direct block
 *
 * Return:	Pointer to new direct block on success, NULL on failure
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Feb 27 2006
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblock,
    unsigned par_entry, haddr_t *addr_p, H5HF_free_section_t **ret_sec_node)
{
    H5HF_free_section_t *sec_node; /* Pointer to free space section for block */
    H5HF_direct_t *dblock = NULL;       /* Pointer to direct block */
    haddr_t dblock_addr;                /* Direct block's address */
    size_t free_space;                  /* Free space in new block */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_NOINIT

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

    /*
     * Allocate file and memory data structures.
     */
    if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fractal heap direct block")

    /* Reset the metadata cache info for the heap header */
    HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t));

    /* Share common heap information */
    dblock->hdr = hdr;
    if(H5HF_hdr_incr(hdr) < 0)
	HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header")

    /* Set info for direct block */
    if(par_iblock) {
        unsigned par_row = par_entry / hdr->man_dtable.cparam.width;    /* Row for block */

        /* Compute offset & size, based on parent's information */
        dblock->block_off = par_iblock->block_off;
        dblock->block_off += hdr->man_dtable.row_block_off[par_row];
        dblock->block_off += hdr->man_dtable.row_block_size[par_row] * (par_entry % hdr->man_dtable.cparam.width);
        H5_CHECKED_ASSIGN(dblock->size, size_t, hdr->man_dtable.row_block_size[par_row], hsize_t);
    } /* end if */
    else {
        /* Must be the root direct block */
        dblock->block_off = 0;
        dblock->size = hdr->man_dtable.cparam.start_block_size;
    } /* end else */
    dblock->file_size = 0;
    free_space = dblock->size - H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);

    /* Allocate buffer for block */
/* XXX: Change to using free-list factories */
    if((dblock->blk = H5FL_BLK_MALLOC(direct_block, dblock->size)) == NULL)
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
#ifdef H5_CLEAR_MEMORY
HDmemset(dblock->blk, 0, dblock->size);
#endif /* H5_CLEAR_MEMORY */

    dblock->write_buf = NULL;
    dblock->write_size = 0;

    /* Allocate [temporary] space for the direct block on disk */
    if(H5F_USE_TMP_SPACE(hdr->f)) {
        if(HADDR_UNDEF == (dblock_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)dblock->size)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
    } /* end if */
    else {
        if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
Exemple #4
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);
}
Exemple #5
0
/*-------------------------------------------------------------------------
 * Function:	H5HF_man_dblock_create
 *
 * Purpose:	Allocate & initialize a managed direct block
 *
 * Return:	Pointer to new direct block on success, NULL on failure
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Feb 27 2006
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblock,
    unsigned par_entry, haddr_t *addr_p, H5HF_free_section_t **ret_sec_node)
{
    H5HF_free_section_t *sec_node; /* Pointer to free space section for block */
    H5HF_direct_t *dblock = NULL;       /* Pointer to direct block */
    haddr_t dblock_addr;                /* Direct block's address */
    size_t free_space;                  /* Free space in new block */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_create)

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

    /*
     * Allocate file and memory data structures.
     */
    if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fractal heap direct block")

    /* Reset the metadata cache info for the heap header */
    HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t));

    /* Share common heap information */
    dblock->hdr = hdr;
    if(H5HF_hdr_incr(hdr) < 0)
	HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header")

    /* Set info for direct block */
    if(par_iblock) {
        unsigned par_row = par_entry / hdr->man_dtable.cparam.width;    /* Row for block */

        /* Compute offset & size, based on parent's information */
        dblock->block_off = par_iblock->block_off;
        dblock->block_off += hdr->man_dtable.row_block_off[par_row];
        dblock->block_off += hdr->man_dtable.row_block_size[par_row] * (par_entry % hdr->man_dtable.cparam.width);
        H5_ASSIGN_OVERFLOW(/* To: */ dblock->size, /* From: */ hdr->man_dtable.row_block_size[par_row], /* From: */ hsize_t, /* To: */ size_t);
    } /* end if */
    else {
        /* Must be the root direct block */
        dblock->block_off = 0;
        dblock->size = hdr->man_dtable.cparam.start_block_size;
    } /* end else */
    dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size);
    free_space = dblock->size - H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);

    /* Allocate buffer for block */
/* XXX: Change to using free-list factories */
    if((dblock->blk = H5FL_BLK_MALLOC(direct_block, dblock->size)) == NULL)
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
#ifdef H5_CLEAR_MEMORY
HDmemset(dblock->blk, 0, dblock->size);
#endif /* H5_CLEAR_MEMORY */

    /* Allocate space for the direct block on disk */
    if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
#ifdef QAK
HDfprintf(stderr, "%s: direct block address = %a\n", FUNC, dblock_addr);
#endif /* QAK */

    /* Attach to parent indirect block, if there is one */
    dblock->parent = par_iblock;
    if(dblock->parent)
        if(H5HF_man_iblock_attach(dblock->parent, par_entry, dblock_addr) < 0)
            HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't attach direct block to parent indirect block")
    dblock->par_entry = par_entry;

    /* Create a new 'single' section for the free space in the block */
    if(NULL == (sec_node = H5HF_sect_single_new((dblock->block_off + H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)),
            free_space, dblock->parent, dblock->par_entry)))
        HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create section for new direct block's free space")

    /* Check what to do with section node */
    if(ret_sec_node)
        /* Pass back the pointer to the section instead of adding it to the free list */
        *ret_sec_node = sec_node;
    else {
        /* Add new free space to the heap's list of space */
        if(H5HF_space_add(hdr, dxpl_id, sec_node, 0) < 0)
            HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list")
    } /* end else */

    /* Cache the new fractal heap direct block */
    if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
	HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap direct block to cache")

    /* Increase the allocated heap size */
    if(H5HF_hdr_inc_alloc(hdr, dblock->size) < 0)
        HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size")

    /* Set the address of of direct block, if requested */
    if(addr_p)
        *addr_p = dblock_addr;

done:
    if(ret_value < 0)
        if(dblock)
            (void)H5HF_cache_dblock_dest(hdr->f, dblock);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_dblock_create() */