/*------------------------------------------------------------------------- * 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 */
/**************************************************************** ** ** 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() */
/*------------------------------------------------------------------------- * 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)))
/*-------------------------------------------------------------------------- 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); }
/*------------------------------------------------------------------------- * 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() */