void fmt_print(uint8 *x, int32 type) { int16 s = 0; int32 l = 0; float32 f = 0; float64 d = 0; switch(type) { case DFNT_CHAR: putchar(*x); break; case DFNT_UINT8: case DFNT_INT8: printf("%02x ", *x); break; case DFNT_UINT16: case DFNT_INT16: HDmemcpy(&s, x, sizeof(int16)); printf("%d", s); break; case DFNT_UINT32: HDmemcpy(&l, x, sizeof(int32)); printf("%u", l); break; case DFNT_INT32: HDmemcpy(&l, x, sizeof(int32)); printf("%d", l); break; case DFNT_FLOAT32: HDmemcpy(&f, x, sizeof(float32)); printf("%f", f); break; case DFNT_FLOAT64: HDmemcpy(&d, x, sizeof(float64)); printf("%f", d); break; default: fprintf(stderr,"sorry, type [%d] not supported\n", type); break; } }
/*---------------------------------------------------------------------------- * Name: h5rcreate_region_c * Purpose: Call H5Rcreate to create a reference to dataset region * region * Inputs: loc_id - file or group identifier * name - name of the dataset * namelen - name length * space_id - dataset space identifier * Outputs: ref - reference to the dataset region * Returns: 0 on success, -1 on failure * Programmer: Elena Pourmal * Wednesday, December 1, 1999 * Modifications: *---------------------------------------------------------------------------*/ int_f nh5rcreate_region_c (int_f *ref, hid_t_f *loc_id, _fcd name, int_f *namelen, hid_t_f *space_id) { int ret_value = -1; hid_t c_loc_id; hid_t c_space_id; int ret_value_c; char *c_name; int c_namelen; hdset_reg_ref_t ref_c; /* * Convert FORTRAN name to C name */ c_namelen = *namelen; c_name = (char *)HD5f2cstring(name, c_namelen); if (c_name == NULL) return ret_value; /* * Call H5Rcreate function. */ c_loc_id = *loc_id; c_space_id = *space_id; ret_value_c = H5Rcreate(&ref_c, c_loc_id, c_name, H5R_DATASET_REGION, c_space_id); HDfree(c_name); if (ret_value_c >= 0) { HDmemcpy (ref, &ref_c, H5R_DSET_REG_REF_BUF_SIZE); ret_value = 0; } return ret_value; }
/*------------------------------------------------------------------------- * Function: H5O_layout_encode * * Purpose: Encodes a message. * * Return: Non-negative on success/Negative on failure * * 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 herr_t H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg) { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; unsigned u; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_layout_encode); /* check args */ assert(f); assert(mesg); assert(mesg->version>0); assert(p); /* Version */ *p++ = mesg->version; /* Check for which information to write */ if(mesg->version<3) { /* number of dimensions */ if(mesg->type!=H5D_CHUNKED) { assert(mesg->unused.ndims > 0 && mesg->unused.ndims <= H5O_LAYOUT_NDIMS); *p++ = mesg->unused.ndims; } /* end if */ else { assert(mesg->u.chunk.ndims > 0 && mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS); *p++ = mesg->u.chunk.ndims; } /* end else */ /* layout class */ *p++ = mesg->type; /* reserved bytes should be zero */ for (u=0; u<5; u++) *p++ = 0; /* data or B-tree address */ if(mesg->type==H5D_CONTIGUOUS) H5F_addr_encode(f, &p, mesg->u.contig.addr); else if(mesg->type==H5D_CHUNKED) H5F_addr_encode(f, &p, mesg->u.chunk.addr); /* Dimension sizes */ if(mesg->type!=H5D_CHUNKED) for (u = 0; u < mesg->unused.ndims; u++) UINT32ENCODE(p, mesg->unused.dim[u]) else for (u = 0; u < mesg->u.chunk.ndims; u++) UINT32ENCODE(p, mesg->u.chunk.dim[u]); if(mesg->type==H5D_COMPACT) { UINT32ENCODE(p, mesg->u.compact.size); if(mesg->u.compact.size>0 && mesg->u.compact.buf) { HDmemcpy(p, mesg->u.compact.buf, mesg->u.compact.size); p += mesg->u.compact.size; } } } /* end if */ else {
/*------------------------------------------------------------------------- * Function: allocate_and_init_2D_array * * Purpose: Initialize an array as a pseudo 2D array and copy in some * initial values. * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ static herr_t allocate_and_init_2D_array(int ***arr, const hsize_t *sizes, int **initial_values) { size_t r, c; /* Data rows and columns */ size_t i; /* Iterator */ size_t n_bytes; /* # of bytes to copy */ r = (size_t)sizes[0]; c = (size_t)sizes[1]; /* Allocate and set up pseudo-2D array */ if (NULL == (*arr = (int **)HDcalloc(r, sizeof(int *)))) TEST_ERROR; if (NULL == ((*arr)[0] = (int *)HDcalloc(r * c, sizeof(int)))) TEST_ERROR; for (i = 0; i < r; i++) (*arr)[i] = (**arr + c * i); /* Copy over the data elements */ if (initial_values) { n_bytes = r * c * sizeof(int); HDmemcpy((*arr)[0], initial_values[0], n_bytes); } return SUCCEED; error: free_2D_array(arr); return FAIL; } /* end allocate_and_init_2D_array() */
/*------------------------------------------------------------------------- * Function: H5O_fill_new_encode * * Purpose: Encode 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: Non-negative on success/Negative on failure * * Programmer: Raymond Lu * Feb 26, 2002 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5O_fill_new_encode(H5F_t UNUSED *f, uint8_t *p, const void *_mesg) { const H5O_fill_new_t *mesg = (const H5O_fill_new_t *)_mesg; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fill_new_encode); assert(f); assert(p); assert(mesg && NULL==mesg->type); /* Version */ *p++ = H5O_FILL_VERSION; /* Space allocation time */ *p++ = mesg->alloc_time; /* Fill value writing time */ *p++ = mesg->fill_time; /* Whether fill value is defined */ *p++ = mesg->fill_defined; /* Does it handle undefined fill value? */ INT32ENCODE(p, mesg->size); if(mesg->size>0) if(mesg->buf) { H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t); HDmemcpy(p, mesg->buf, (size_t)mesg->size); } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED); }
/*------------------------------------------------------------------------- * Function: H5F__drvrinfo_prefix_decode * * Purpose: Decode a driver info prefix * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * December 15, 2016 * *------------------------------------------------------------------------- */ static herr_t H5F__drvrinfo_prefix_decode(H5O_drvinfo_t *drvrinfo, char *drv_name, const uint8_t **image_ref, H5F_drvrinfo_cache_ud_t *udata, hbool_t extend_eoa) { const uint8_t *image = (const uint8_t *)*image_ref; /* Pointer into raw data buffer */ unsigned drv_vers; /* Version of driver info block */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Sanity check */ HDassert(drvrinfo); HDassert(image_ref); HDassert(image); HDassert(udata); HDassert(udata->f); /* Version number */ drv_vers = *image++; if(drv_vers != HDF5_DRIVERINFO_VERSION_0) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad driver information block version number") image += 3; /* reserved bytes */ /* Driver info size */ UINT32DECODE(image, drvrinfo->len); /* Driver name and/or version */ if(drv_name) { HDmemcpy(drv_name, (const char *)image, (size_t)8); drv_name[8] = '\0'; image += 8; /* advance past name/version */ } /* end if */ /* Extend the EOA if required so that we can read the complete driver info block */ if(extend_eoa) { haddr_t eoa; /* Current EOA for the file */ haddr_t min_eoa; /* Minimum EOA needed for reading the driver info */ /* Get current EOA... */ eoa = H5FD_get_eoa(udata->f->shared->lf, H5FD_MEM_SUPER); if(!H5F_addr_defined(eoa)) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "driver get_eoa request failed") /* ... if it is too small, extend it. */ min_eoa = udata->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drvrinfo->len; /* If it grew, set it */ if(H5F_addr_gt(min_eoa, eoa)) if(H5FD_set_eoa(udata->f->shared->lf, H5FD_MEM_SUPER, min_eoa) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed") } /* end if */ /* Update the image buffer pointer */ *image_ref = image; done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__drvrinfo_prefix_decode() */
/*------------------------------------------------------------------------- * 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); }
/**************************************************************** ** ** test_skiplist_init(): Test H5SL (skiplist) code. ** Initialize data for skip list testing ** ****************************************************************/ static void test_skiplist_init(void) { time_t curr_time; /* Current time, for seeding random number generator */ int new_val; /* New value to insert */ unsigned found; /* Flag to indicate value was inserted already */ size_t u,v; /* Local index variables */ /* Initialize random number seed */ curr_time = HDtime(NULL); HDsrandom((unsigned)curr_time); /* Create randomized set of numbers */ for(u=0; u<NUM_ELEMS; u++) { do { /* Reset flag */ found=0; /* Generate random numbers from -5000 to 5000 */ new_val=(int)(HDrandom()%10001)-5001; /* Check if the value is already in the array */ for(v=0; v<u; v++) if(rand_num[v]==new_val) found=1; } while(found); /* Set unique value in array */ rand_num[u]=new_val; } /* end for */ /* Copy random values to sorted array */ HDmemcpy(sort_rand_num,rand_num,sizeof(int)*NUM_ELEMS); /* Sort random numbers */ HDqsort(sort_rand_num, (size_t)NUM_ELEMS, sizeof(int), tst_sort); /* Copy random values to reverse sorted array */ HDmemcpy(rev_sort_rand_num, rand_num, sizeof(int) * NUM_ELEMS); /* Sort random numbers */ HDqsort(rev_sort_rand_num, (size_t)NUM_ELEMS, sizeof(int), tst_rev_sort); } /* end test_tst_init() */
/*------------------------------------------------------------------------- * Function: H5O_fill_new_decode * * Purpose: Decode a new fill value message. The new fill value * message is fill value plus space allocation time and * fill value writing time and whether fill value is defined. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * * Programmer: Raymond Lu * Feb 26, 2002 * * Modifications: * *------------------------------------------------------------------------- */ static void * H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p) { H5O_fill_new_t *mesg=NULL; int version; void *ret_value; FUNC_ENTER_NOAPI_NOINIT(H5O_fill_new_decode); assert(f); assert(p); if (NULL==(mesg=H5FL_CALLOC(H5O_fill_new_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message"); /* Version */ version = *p++; if( version != H5O_FILL_VERSION && version !=H5O_FILL_VERSION_2) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for fill value message"); /* Space allocation time */ mesg->alloc_time = (H5D_alloc_time_t)*p++; /* Fill value write time */ mesg->fill_time = (H5D_fill_time_t)*p++; /* Whether fill value is defined */ mesg->fill_defined = *p++; /* Only decode fill value information if one is defined */ if(mesg->fill_defined) { INT32DECODE(p, mesg->size); if (mesg->size>0) { H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t); if (NULL==(mesg->buf=H5MM_malloc((size_t)mesg->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value"); HDmemcpy(mesg->buf, p, (size_t)mesg->size); } } /* end if */ else mesg->size=(-1); /* Set return value */ ret_value = (void*)mesg; done: if (!ret_value && mesg) { if(mesg->buf) H5MM_xfree(mesg->buf); H5FL_FREE(H5O_fill_new_t,mesg); } FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: H5O_fill_copy_dyn * * Purpose: Copy dynamic fill value fields * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, May 31, 2007 * *------------------------------------------------------------------------- */ static herr_t H5O_fill_copy_dyn(H5O_fill_t *dest, const H5O_fill_t *mesg) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_fill_copy_dyn) HDassert(dest); HDassert(mesg); /* Copy data type of fill value */ if(mesg->type) { if(NULL == (dest->type = H5T_copy(mesg->type, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy fill value data type"); } /* end if */ else dest->type = NULL; /* Copy fill value and its size */ if(mesg->buf) { H5_CHECK_OVERFLOW(mesg->size,ssize_t,size_t); if(NULL == (dest->buf = H5MM_malloc((size_t)mesg->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fill value"); HDmemcpy(dest->buf, mesg->buf, (size_t)mesg->size); /* Check for needing to convert/copy fill value */ if(mesg->type) { H5T_path_t *tpath; /* Conversion information */ /* Set up type conversion function */ if(NULL == (tpath = H5T_path_find(mesg->type, dest->type, NULL, NULL, H5AC_ind_dxpl_id))) HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types") /* If necessary, convert fill value datatypes (which copies VL components, etc.) */ if(!H5T_path_noop(tpath)) { hid_t dst_id, src_id; /* Source & destination datatypes for type conversion */ uint8_t *bkg_buf = NULL; /* Background conversion buffer */ size_t bkg_size; /* Size of background buffer */ /* Wrap copies of types to convert */ dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dest->type, H5T_COPY_TRANSIENT)); if(dst_id < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype") src_id = H5I_register(H5I_DATATYPE, H5T_copy(mesg->type, H5T_COPY_ALL)); if(src_id < 0) { H5I_dec_ref(dst_id); HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype") } /* end if */
/****if* H5Df/h5dwrite_ref_reg_c * NAME * h5dwrite_ref_reg_c * PURPOSE * Call H5Dwrite to write a dataset of dataset region references * INPUTS * dset_id - dataset identifier * mem_type_id - memory datatype identifier * mem_space_id - memory dataspace identifier * file_space_id - memory dataspace identifier * xfer_pr - identifier of transfer property list * buf - data buffer with references to the objects. * n - number of references to be stored. * RETURNS * 0 on success, -1 on failure * AUTHOR * Elena Pourmal * Tuesday, May 14, 2002 * HISTORY * This function was added to accomodate h5dwrite_f with the * dims argument being of INTEGER(HSIZE_T) type * SOURCE */ int_f h5dwrite_ref_reg_c (hid_t_f *dset_id, hid_t_f *mem_type_id, hid_t_f *mem_space_id, hid_t_f *file_space_id, hid_t_f *xfer_prp, int_f *buf, hsize_t_f *dims) /******/ { int ret_value = -1; herr_t ret; hid_t c_dset_id; hid_t c_mem_type_id; hid_t c_mem_space_id; hid_t c_file_space_id; hid_t c_xfer_prp; hdset_reg_ref_t *buf_c = NULL; unsigned int i, n; n = (unsigned int)*dims; /* * Define transfer property */ c_xfer_prp = (hid_t)*xfer_prp; /* * Allocate temporary buffer and copy references from Fortran. */ buf_c = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t)*n); if ( buf_c != NULL ) { for (i = 0; i < n; i++) { HDmemcpy(&buf_c[i], buf, H5R_DSET_REG_REF_BUF_SIZE); buf = buf + REF_REG_BUF_LEN_F; } } else return ret_value; /* * Call H5Dwrite function. */ c_dset_id = (hid_t)*dset_id; c_mem_type_id = (hid_t)*mem_type_id; c_mem_space_id = (hid_t)*mem_space_id; c_file_space_id = (hid_t)*file_space_id; ret = H5Dwrite(c_dset_id, c_mem_type_id, c_mem_space_id, c_file_space_id, c_xfer_prp, buf_c); HDfree(buf_c); if (ret < 0) return ret_value; ret_value = 0; return ret_value; }
/*------------------------------------------------------------------------- * Function: H5O_fill_encode * * Purpose: Encode a fill value message. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Thursday, October 1, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5O_fill_encode(H5F_t UNUSED *f, uint8_t *p, const void *_mesg) { const H5O_fill_t *mesg = (const H5O_fill_t *)_mesg; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_fill_encode); assert(f); assert(p); assert(mesg && NULL==mesg->type); UINT32ENCODE(p, mesg->size); if(mesg->buf) HDmemcpy(p, mesg->buf, mesg->size); FUNC_LEAVE_NOAPI(SUCCEED); }
/* NAME HDf2cstring -- convert a Fortran string to a C string USAGE char * HDf2cstring(fdesc, len) _fcd fdesc; IN: Fortran string descriptor intn len; IN: length of Fortran string RETURNS Pointer to the C string if success, else NULL DESCRIPTION Chop off trailing blanks off of a Fortran string and move it into a newly allocated C string. It is up to the user to free this string. ---------------------------------------------------------------------------*/ char * HDf2cstring(_fcd fdesc, intn len) { CONSTR(FUNC, "HDf2cstring"); /* for HERROR */ char *cstr, *str; int i; str = _fcdtocp(fdesc); /* This should be equivalent to the above test -QAK */ for(i=len-1; i>=0 && !isgraph((int)str[i]); i--) /*EMPTY*/; cstr = (char *) HDmalloc((uint32) (i + 2)); if (!cstr) HRETURN_ERROR(DFE_NOSPACE, NULL); cstr[i + 1] = '\0'; HDmemcpy(cstr,str,i+1); return cstr; } /* HDf2cstring */
/****if* H5Df/h5dread_ref_reg_c * NAME * h5dread_ref_reg_c * PURPOSE * Call H5Dread to read a dataset of dataset region references * INPUTS * dset_id - dataset identifier * mem_type_id - memory datatype identifier * mem_space_id - memory dataspace identifier * file_space_id - memory dataspace identifier * xfer_pr - identifier of transfer property list * buf - data buffer to store references to the objects. * n - number of references to be stored. * RETURNS * 0 on success, -1 on failure * AUTHOR * Elena Pourmal * Wednesday, May 15, 2002 * HISTORY * This function was added to accomodate h5dread_f subroutine * with the dims parameter being of INTEGER(HSIZE_T_F) size. * SOURCE */ int_f h5dread_ref_reg_c (hid_t_f *dset_id, hid_t_f *mem_type_id, hid_t_f *mem_space_id, hid_t_f *file_space_id, hid_t_f *xfer_prp, int_f * buf, hsize_t_f *dims) /******/ { int ret_value = -1; herr_t ret = -1; hid_t c_dset_id; hid_t c_mem_type_id; hid_t c_mem_space_id; hid_t c_file_space_id; hid_t c_xfer_prp; hdset_reg_ref_t *buf_c = NULL; hsize_t i, n; n = (hsize_t)*dims; /* * Define transfer property */ c_xfer_prp = (hid_t)*xfer_prp; /* * Allocate temporary buffer. */ buf_c = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t)*(size_t)n); if ( buf_c != NULL ) { /* * Call H5Dread function. */ c_dset_id = (hid_t)*dset_id; c_mem_type_id = (hid_t)*mem_type_id; c_mem_space_id = (hid_t)*mem_space_id; c_file_space_id = (hid_t)*file_space_id; ret = H5Dread(c_dset_id, c_mem_type_id, c_mem_space_id, c_file_space_id, c_xfer_prp, buf_c); if (ret >=0) { for (i = 0; i < n; i++) { HDmemcpy(buf, &buf_c[i], H5R_DSET_REG_REF_BUF_SIZE); buf = buf + REF_REG_BUF_LEN_F; } } if ( buf_c != NULL ) HDfree(buf_c); } if (ret < 0) return ret_value; ret_value = 0; return ret_value; }
int read_wo_file(void) { int read_fd; int blkaddr=0; int ret_code; int linkedblocks_read=0; char buffer[BLOCKSIZE_DFT]; /* Open the data file */ if ((read_fd = HDopen(DATAFILE, O_RDONLY, 0)) < 0) { printf("READER: error from open\n"); return -1; } /* keep reading the initial block address until it is non-zero before proceeding. */ while (blkaddr == 0){ HDlseek(read_fd, (HDoff_t)0, SEEK_SET); if ((ret_code=HDread(read_fd, &blkaddr, (size_t)sizeof(blkaddr))) != sizeof(blkaddr)){ printf("blkaddr read failed in partition %d\n", 0); return -1; } } linkedblocks_read++; /* got a non-zero blkaddr. Proceed down the linked blocks. */ #ifdef DEBUG printf("got initial block address=%d\n", blkaddr); #endif while (blkaddr != 0){ HDlseek(read_fd, (HDoff_t)blkaddr, SEEK_SET); if ((ret_code=HDread(read_fd, buffer, (size_t)blocksize_g)) != blocksize_g){ printf("blkaddr read failed in partition %d\n", 0); return -1; } linkedblocks_read++; /* retrieve the block address in byte 0-3 */ HDmemcpy(&blkaddr, &buffer[0], sizeof(blkaddr)); #ifdef DEBUG printf("got next block address=%d\n", blkaddr); #endif } printf("read %d blocks\n", linkedblocks_read); return 0; }
/*------------------------------------------------------------------------- * Function: H5O_layout_copy * * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if * necessary. * * Return: Success: Ptr to _DEST * * Failure: NULL * * Programmer: Robb Matzke * Wednesday, October 8, 1997 * *------------------------------------------------------------------------- */ static void * H5O_layout_copy(const void *_mesg, void *_dest) { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; H5O_layout_t *dest = (H5O_layout_t *) _dest; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_layout_copy) /* check args */ HDassert(mesg); /* Allocate destination message, if necessary */ if(!dest && NULL == (dest = H5FL_MALLOC(H5O_layout_t))) HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "layout message allocation failed") /* copy */ *dest = *mesg; /* Deep copy the buffer for compact datasets also */ if(mesg->type == H5D_COMPACT && mesg->storage.u.compact.size > 0) { /* Allocate memory for the raw data */ if(NULL == (dest->storage.u.compact.buf = H5MM_malloc(dest->storage.u.compact.size))) HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset") /* Copy over the raw data */ HDmemcpy(dest->storage.u.compact.buf, mesg->storage.u.compact.buf, dest->storage.u.compact.size); } /* end if */ /* Reset the pointer of the chunked storage index but not the address */ if(dest->type == H5D_CHUNKED && dest->storage.u.chunk.ops) H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE); /* Set return value */ ret_value = dest; done: if(ret_value == NULL) if(NULL == _dest) dest = H5FL_FREE(H5O_layout_t, dest); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_copy() */
/*---------------------------------------------------------------------------- * Name: h5rdereference_region_c * Purpose: Call H5Rdereference to dereference to dataset region * Inputs: dset_id - dataset identifier * ref - reference to the dataset region * Outputs: obj_id - dereferenced dataset identifier * Returns: 0 on success, -1 on failure * Programmer: Elena Pourmal * Wednesday, December 1, 1999 * Modifications: *---------------------------------------------------------------------------*/ int_f nh5rdereference_region_c (hid_t_f *dset_id, int_f *ref, hid_t_f *obj_id) { int ret_value = -1; hid_t c_dset_id; hdset_reg_ref_t ref_c; hid_t c_obj_id; HDmemcpy (&ref_c, ref, H5R_DSET_REG_REF_BUF_SIZE); /* * Call H5Rdereference function. */ c_dset_id = *dset_id; c_obj_id = H5Rdereference(c_dset_id, H5R_DATASET_REGION, &ref_c); if(c_obj_id < 0) return ret_value; *obj_id = (hid_t_f)c_obj_id; ret_value = 0; return ret_value; }
/*---------------------------------------------------------------------------- * Name: h5rget_region_region_object_c * Purpose: Call H5Rget_region to dereference dataspace region * Inputs: dset_id - dataset identifier * ref - reference to the dataset region * Outputs: space_id - dereferenced dataset dataspace identifier * Returns: 0 on success, -1 on failure * Programmer: Elena Pourmal * Wednesday, December 1, 1999 * Modifications: *---------------------------------------------------------------------------*/ int_f nh5rget_region_region_c (hid_t_f *dset_id, int_f *ref, hid_t_f *space_id) { int ret_value = -1; hid_t c_dset_id; hid_t c_space_id; hdset_reg_ref_t ref_c; HDmemcpy (&ref_c, ref, H5R_DSET_REG_REF_BUF_SIZE); /* * Call H5Rget_region function. */ c_dset_id = *dset_id; c_space_id = H5Rget_region(c_dset_id, H5R_DATASET_REGION, &ref_c); if(c_space_id < 0) return ret_value; *space_id = (hid_t_f)c_space_id; ret_value = 0; return ret_value; }
/*------------------------------------------------------------------------- * Function: H5D__scatter_file * * Purpose: Scatters dataset elements from the type conversion buffer BUF * to the file F where the data points are arranged according to * the file dataspace FILE_SPACE and stored according to * LAYOUT and EFL. Each element is ELMT_SIZE bytes. * The caller is requesting that NELMTS elements are copied. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, June 20, 2002 * *------------------------------------------------------------------------- */ static herr_t H5D__scatter_file(const H5D_io_info_t *_io_info, const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts, const void *_buf) { H5D_io_info_t tmp_io_info; /* Temporary I/O info object */ hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */ hsize_t *off = NULL; /* Pointer to sequence offsets */ hsize_t mem_off; /* Offset in memory */ size_t mem_curr_seq; /* "Current sequence" in memory */ size_t dset_curr_seq; /* "Current sequence" in dataset */ size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */ size_t *len = NULL; /* Array to store sequence lengths */ size_t orig_mem_len, mem_len; /* Length of sequence in memory */ size_t nseq; /* Number of sequences generated */ size_t nelem; /* Number of elements used in sequences */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Check args */ HDassert(_io_info); HDassert(space); HDassert(iter); HDassert(nelmts > 0); HDassert(_buf); /* Set up temporary I/O info object */ HDmemcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); tmp_io_info.op_type = H5D_IO_OP_WRITE; tmp_io_info.u.wbuf = _buf; /* Allocate the vector I/O arrays */ if(tmp_io_info.dxpl_cache->vec_size > H5D_IO_VECTOR_SIZE) { if(NULL == (len = H5FL_SEQ_MALLOC(size_t, tmp_io_info.dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array") if(NULL == (off = H5FL_SEQ_MALLOC(hsize_t, tmp_io_info.dxpl_cache->vec_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array") } /* end if */ else {
int write_wo_file(void) { int blkaddr; int blkaddr_old=0; int i; char buffer[BLOCKSIZE_DFT]; int ret_code; /* write block 1, 2, ... */ for (i=1; i<nlinkedblock_g; i++){ /* calculate where to write this block */ blkaddr = i*part_size_g + i; /* store old block address in byte 0-3 */ HDmemcpy(&buffer[0], &blkaddr_old, sizeof(blkaddr_old)); /* fill the rest with the lowest byte of i */ HDmemset(&buffer[4], i & 0xff, (size_t) (BLOCKSIZE_DFT-4)); /* write the block */ #ifdef DEBUG printf("writing block at %d\n", blkaddr); #endif HDlseek(write_fd_g, (HDoff_t)blkaddr, SEEK_SET); if ((ret_code=HDwrite(write_fd_g, buffer, (size_t)blocksize_g)) != blocksize_g){ printf("blkaddr write failed in partition %d\n", i); return -1; } blkaddr_old = blkaddr; } /* write the last blkaddr in partition 0 */ HDlseek(write_fd_g, (HDoff_t)0, SEEK_SET); if ((ret_code=HDwrite(write_fd_g, &blkaddr_old, (size_t)sizeof(blkaddr_old))) != sizeof(blkaddr_old)){ printf("blkaddr write failed in partition %d\n", 0); return -1; } /* all writes done. return succeess. */ printf("wrote %d blocks\n", nlinkedblock_g); return 0; }
/*------------------------------------------------------------------------- * Function: H5O_drvinfo_decode * * Purpose: Decode a shared message table message and return a pointer * to a newly allocated H5O_drvinfo_t struct. * * Return: Success: Ptr to new message in native struct. * Failure: NULL * * Programmer: Quincey Koziol * Mar 1, 2007 * *------------------------------------------------------------------------- */ static void * H5O_drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) { H5O_drvinfo_t *mesg; /* Native message */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity check */ HDassert(f); HDassert(p); /* Version of message */ if(*p++ != H5O_DRVINFO_VERSION) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message") /* Allocate space for message */ if(NULL == (mesg = (H5O_drvinfo_t *)H5MM_calloc(sizeof(H5O_drvinfo_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info message") /* Retrieve driver name */ HDmemcpy(mesg->name, p, 8); mesg->name[8] = '\0'; p += 8; /* Decode buffer size */ UINT16DECODE(p, mesg->len); HDassert(mesg->len); /* Allocate space for buffer */ if(NULL == (mesg->buf = (uint8_t *)H5MM_malloc(mesg->len))) { mesg = (H5O_drvinfo_t *)H5MM_xfree(mesg); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info buffer") } /* end if */
/*------------------------------------------------------------------------- * Function: H5SM_bt2_convert_to_list_op * * Purpose: An H5B2_remove_t callback function to convert a SOHM * B-tree index to a list. * * Inserts this record into the list passed through op_data. * * Return: Non-negative on success * Negative on failure * * Programmer: James Laird * Monday, November 6, 2006 * *------------------------------------------------------------------------- */ herr_t H5SM_bt2_convert_to_list_op(const void * record, void *op_data) { const H5SM_sohm_t *message = (const H5SM_sohm_t *)record; const H5SM_list_t *list = (const H5SM_list_t *)op_data; size_t mesg_idx; /* Index of message to modify */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ HDassert(record); HDassert(op_data); /* Get the message index, and increment the # of messages in list */ mesg_idx = list->header->num_messages++; HDassert(list->header->num_messages <= list->header->list_max); /* Insert this message at the end of the list */ HDassert(list->messages[mesg_idx].location == H5SM_NO_LOC); HDassert(message->location != H5SM_NO_LOC); HDmemcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t)); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5SM_bt2_convert_to_list_op() */
/*------------------------------------------------------------------------- * 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 */
/*------------------------------------------------------------------------- * Function: H5G_namei * * Purpose: Translates a name to a symbol table entry. * * If the specified name can be fully resolved, then this * function returns the symbol table entry for the named object * through the OBJ_ENT argument. The symbol table entry for the * group containing the named object is returned through the * GRP_ENT argument if it is non-null. However, if the name * refers to the root object then the GRP_ENT will be * initialized with an undefined object header address. The * REST argument, if present, will point to the null terminator * of NAME. * * If the specified name cannot be fully resolved, then OBJ_ENT * is initialized with the undefined object header address. The * REST argument will point into the NAME argument to the start * of the component that could not be located. The GRP_ENT will * contain the entry for the symbol table that was being * searched at the time of the failure and will have an * undefined object header address if the search failed at the * root object. For instance, if NAME is `/foo/bar/baz' and the * root directory exists and contains an entry for `foo', and * foo is a group that contains an entry for bar, but bar is not * a group, then the results will be that REST points to `baz', * OBJ_ENT has an undefined object header address, and GRP_ENT * is the symbol table entry for `bar' in `/foo'. * * Every file has a root group whose name is `/'. Components of * a name are separated from one another by one or more slashes * (/). Slashes at the end of a name are ignored. If the name * begins with a slash then the search begins at the root group * of the file containing LOC_ENT. Otherwise it begins at * LOC_ENT. The component `.' is a no-op, but `..' is not * understood by this function (unless it appears as an entry in * the symbol table). * * Symbolic links are followed automatically, but if TARGET * includes the H5G_TARGET_SLINK bit and the last component of * the name is a symbolic link then that link is not followed. * The *NLINKS value is decremented each time a link is followed * and link traversal fails if the value would become negative. * If NLINKS is the null pointer then a default value is used. * * Mounted files are handled by calling H5F_mountpoint() after * each step of the translation. If the input argument to that * function is a mount point then the argument shall be replaced * with information about the root group of the mounted file. * But if TARGET includes the H5G_TARGET_MOUNT bit and the last * component of the name is a mount point then H5F_mountpoint() * is not called and information about the mount point itself is * returned. * * Errors: * * Return: Success: Non-negative if name can be fully resolved. * See above for values of REST, GRP_ENT, and * OBJ_ENT. NLINKS has been decremented for * each symbolic link that was followed. * * Failure: Negative if the name could not be fully * resolved. See above for values of REST, * GRP_ENT, and OBJ_ENT. * * Programmer: Robb Matzke * [email protected] * Aug 11 1997 * * Modifications: * Robb Matzke, 2002-03-28 * The component name buffer on the stack has been replaced by * a dynamically allocated buffer on the heap in order to * remove limitations on the length of a name component. * There are two reasons that the buffer pointer is global: * (1) We want to be able to reuse the buffer without * allocating and freeing it each time this function is * called. * (2) We need to be able to free it from H5G_term_interface() * when the library terminates. * * Pedro Vicente, <*****@*****.**> 22 Aug 2002 * Modified to deep copies of symbol table entries * Added `id to name' support. * * Quincey Koziol, 2003-01-06 * Added "action" and "ent" parameters to allow different actions when * working on the last component of a name. (Specifically, this allows * inserting an entry into a group, instead of trying to look it up) * *------------------------------------------------------------------------- */ herr_t H5G_namei(const H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/, H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/, unsigned target, int *nlinks/*out*/, H5G_namei_act_t action, H5G_entry_t *ent, hid_t dxpl_id) { H5G_entry_t _grp_ent; /*entry for current group */ H5G_entry_t _obj_ent; /*entry found */ size_t nchars; /*component name length */ int _nlinks = H5G_NLINKS; const char *s = NULL; unsigned null_obj; /* Flag to indicate this function was called with obj_ent set to NULL */ unsigned null_grp; /* Flag to indicate this function was called with grp_ent set to NULL */ unsigned obj_copy = 0; /* Flag to indicate that the object entry is copied */ unsigned group_copy = 0; /* Flag to indicate that the group entry is copied */ unsigned last_comp = 0; /* Flag to indicate that a component is the last component in the name */ unsigned did_insert = 0; /* Flag to indicate that H5G_stab_insert was called */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_namei); /* Set up "out" parameters */ if (rest) *rest = name; if (!grp_ent) { grp_ent = &_grp_ent; null_grp = 1; } /* end if */ else null_grp = 0; if (!obj_ent) { obj_ent = &_obj_ent; null_obj = 1; } /* end if */ else null_obj = 0; if (!nlinks) nlinks = &_nlinks; /* Check args */ if (!name || !*name) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "no name given"); if (!loc_ent) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "no current working group"); /* * Where does the searching start? For absolute names it starts at the * root of the file; for relative names it starts at CWG. */ /* Check if we need to get the root group's entry */ if('/' == *name) { H5G_t *tmp_grp; /* Temporary pointer to root group of file */ /* Look up root group for starting location */ tmp_grp = H5G_rootof(loc_ent->file); HDassert(tmp_grp); /* Set the location entry to the root group's entry*/ loc_ent = &(tmp_grp->ent); } /* end if */ /* Deep copy of the symbol table entry (duplicates strings) */ if(H5G_ent_copy(obj_ent, loc_ent, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") obj_copy = 1; H5G_ent_reset(grp_ent); /* Check for needing a larger buffer for the individual path name components */ if((HDstrlen(name) + 1) > H5G_comp_alloc_g) { char *new_comp; /* New component buffer */ size_t new_alloc; /* New component buffer size */ new_alloc = MAX3(1024, (2 * H5G_comp_alloc_g), (HDstrlen(name) + 1)); if(NULL == (new_comp = H5MM_realloc(H5G_comp_g, new_alloc))) HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "unable to allocate component buffer") H5G_comp_g = new_comp; H5G_comp_alloc_g = new_alloc; } /* end if */ /* traverse the name */ while ((name = H5G_component(name, &nchars)) && *name) { /* Update the "rest of name" pointer */ if(rest) *rest = name; /* * Copy the component name into a null-terminated buffer so * we can pass it down to the other symbol table functions. */ HDmemcpy(H5G_comp_g, name, nchars); H5G_comp_g[nchars] = '\0'; /* * The special name `.' is a no-op. */ if ('.' == H5G_comp_g[0] && !H5G_comp_g[1]) { name += nchars; continue; } /* end if */ /* * Advance to the next component of the name. */ /* If we've already copied a new entry into the group entry, * it needs to be freed before overwriting it with another entry */ if(group_copy) H5G_name_free(grp_ent); /* Transfer "ownership" of the entry's information to the group entry */ H5G_ent_copy(grp_ent, obj_ent, H5_COPY_SHALLOW); H5G_ent_reset(obj_ent); /* Set flag that we've copied a new entry into the group entry */ group_copy = 1; /* Check if this is the last component of the name */ if(!((s=H5G_component(name+nchars, NULL)) && *s)) last_comp=1; switch(action) { case H5G_NAMEI_TRAVERSE: if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/, dxpl_id )<0) { /* * Component was not found in the current symbol table, possibly * because GRP_ENT isn't a symbol table. */ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found"); } break; case H5G_NAMEI_INSERT: if(!last_comp) { if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/, dxpl_id )<0) { /* * Component was not found in the current symbol table, possibly * because GRP_ENT isn't a symbol table. */ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found"); } } /* end if */ else { did_insert = 1; if(H5G_stab_insert(grp_ent, H5G_comp_g, ent, TRUE, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert name") HGOTO_DONE(SUCCEED); } /* end else */ break; } /* end switch */ /* * If we found a symbolic link then we should follow it. But if this * is the last component of the name and the H5G_TARGET_SLINK bit of * TARGET is set then we don't follow it. */ if(H5G_CACHED_SLINK==obj_ent->type && (0==(target & H5G_TARGET_SLINK) || !last_comp)) { if ((*nlinks)-- <= 0) HGOTO_ERROR (H5E_SYM, H5E_SLINK, FAIL, "too many links"); if (H5G_traverse_slink (grp_ent, obj_ent, nlinks, dxpl_id)<0) HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link traversal failed"); } /* * Resolve mount points to the mounted group. Do not do this step if * the H5G_TARGET_MOUNT bit of TARGET is set and this is the last * component of the name. */ if (0==(target & H5G_TARGET_MOUNT) || !last_comp) H5F_mountpoint(obj_ent/*in,out*/); /* next component */ name += nchars; } /* end while */ /* Update the "rest of name" pointer */ if (rest) *rest = name; /*final null */ /* If this was an insert, make sure that the insert function was actually * called (this catches no-op names like "." and "/") */ if(action == H5G_NAMEI_INSERT && !did_insert) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group already exists"); done: /* If we started with a NULL obj_ent, free the entry information */ if(null_obj || (ret_value < 0 && obj_copy)) H5G_name_free(obj_ent); /* If we started with a NULL grp_ent and we copied something into it, free the entry information */ if(null_grp && group_copy) H5G_name_free(grp_ent); FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * 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() */
/*------------------------------------------------------------------------- * Function: monitor_dataset * * Purpose: To poll a dataset periodically for changes in dimension sizes. * For dataset with unchanged and/or decreased dimension sizes: * it just prints the dimension size changes * For dataset with increase in at least one of its dimension sizes: * it will print the new appended data to the dataset * * Return: Non-negative on success: dataset can be monitored * Negative on failure: dataset cannot be monitored * * Programmer: Vailin Choi; August 2010 * *------------------------------------------------------------------------- */ static herr_t monitor_dataset(hid_t fid, char *dsetname) { hid_t did; /* dataset id */ hid_t sid; /* dataspace id */ int ndims; /* # of dimensions in the dataspace */ int i, u; /* local index variable */ hsize_t prev_dims[H5S_MAX_RANK]; /* current dataspace dimensions */ hsize_t cur_dims[H5S_MAX_RANK]; /* previous dataspace dimensions */ herr_t ret_value = SUCCEED; /* return value */ HDfprintf(stdout, "Monitoring dataset %s...\n", dsetname); /* Open the dataset for minitoring */ if((did = H5Dopen2(fid, dsetname, H5P_DEFAULT)) < 0) { error_msg("error in opening dataset \"%s\"\n", dsetname); ret_value = FAIL; goto done; } if((sid = H5Dget_space(did)) < 0) { error_msg("error in getting dataspace id for dataset \"%s\"\n", dsetname); ret_value = FAIL; goto done; } /* Get the dataset's dimension sizes */ if((ndims = H5Sget_simple_extent_dims(sid, prev_dims, NULL)) < 0) { error_msg("unable to get dimensions sizes for \"%s\"\n", dsetname); ret_value = FAIL; goto done; } while(1) { /* Refreshes the dataset */ if(H5Drefresh(did) < 0) { ret_value = FAIL; goto done; } /* Get the dataset's current dimension sizes */ if(H5LDget_dset_dims(did, cur_dims) < 0) { error_msg("unable to get dimension sizes for \"%s\"\n", dsetname); ret_value = FAIL; goto done; } /* Check the dimension sizes */ for(i = 0; i < ndims; i++) if(cur_dims[i] != prev_dims[i]) break; /* at least one dimension has changed */ if(i != ndims) { /* Printing changes in dimension sizes */ for(u = 0; u < ndims; u++) { HDfprintf(stdout, "dimension %u: %Hu->%Hu", (unsigned)u, prev_dims[u], cur_dims[u]); if(cur_dims[u] > prev_dims[u]) HDfprintf(stdout, " (increases)\n"); else if(cur_dims[u] < prev_dims[u]) HDfprintf(stdout, " (decreases)\n"); else HDfprintf(stdout, " (unchanged)\n"); } /* Printing elements appended to the dataset if there is */ if(!g_monitor_size_only) { /* See if at least one dimension size has increased */ for(u = 0; u < ndims; u++) { int j; hsize_t start[H5S_MAX_RANK]; hsize_t block[H5S_MAX_RANK]; /* Print the new appended data to the dataset */ if(cur_dims[u] > prev_dims[u]) { HDfprintf(stdout, " Data:\n"); for(j = 0; j < ndims; j++) { start[j] = 0; block[j] = 1; } if((ret_value = slicendump(did, prev_dims, cur_dims, start, block, ndims, ndims)) < 0) goto done; break; } } /* end for */ } HDfflush(stdout); } /* Save the current dimension sizes */ HDmemcpy(prev_dims, cur_dims, (size_t)ndims * sizeof(hsize_t)); /* Sleep before next monitor */ HDsleep(g_polling_interval); } /* end while */ done: /* Closing */ H5E_BEGIN_TRY H5Dclose(did); H5E_END_TRY return(ret_value); } /* monitor_dataset() */
/*------------------------------------------------------------------------- * Function: H5O_layout_encode * * Purpose: Encodes a message. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * Wednesday, October 8, 1997 * * Note: * Quincey Koziol, 2004-5-21 * We write out version 3 messages by default now. * * 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. * * Quincey Koziol, 2004-5-21 * Added version number 3 case to straighten out problems with contiguous * layout's sizes (was encoding them as 4-byte values when they were * really n-byte values (where n usually is 8)) and additionally clean up * the information written out. * *------------------------------------------------------------------------- */ static herr_t H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; unsigned u; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_layout_encode) /* check args */ HDassert(f); HDassert(mesg); HDassert(p); /* Message version */ *p++ = (uint8_t)H5O_LAYOUT_VERSION_3; /* Layout class */ *p++ = mesg->type; /* Write out layout class specific information */ switch(mesg->type) { case H5D_COMPACT: /* Size of raw data */ UINT16ENCODE(p, mesg->storage.u.compact.size); /* Raw data */ if(mesg->storage.u.compact.size > 0) { if(mesg->storage.u.compact.buf) HDmemcpy(p, mesg->storage.u.compact.buf, mesg->storage.u.compact.size); else HDmemset(p, 0, mesg->storage.u.compact.size); p += mesg->storage.u.compact.size; } /* end if */ break; case H5D_CONTIGUOUS: H5F_addr_encode(f, &p, mesg->storage.u.contig.addr); H5F_ENCODE_LENGTH(f, p, mesg->storage.u.contig.size); break; case H5D_CHUNKED: /* Number of dimensions */ HDassert(mesg->u.chunk.ndims > 0 && mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS); *p++ = (uint8_t)mesg->u.chunk.ndims; /* B-tree address */ H5F_addr_encode(f, &p, mesg->storage.u.chunk.idx_addr); /* Dimension sizes */ for(u = 0; u < mesg->u.chunk.ndims; u++) UINT32ENCODE(p, mesg->u.chunk.dim[u]); break; default: HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "Invalid layout class") } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_encode() */
/*-------------------------------------------------------------------------- NAME H5O_attr_encode PURPOSE Encode a simple attribute message USAGE herr_t H5O_attr_encode(f, raw_size, p, mesg) H5F_t *f; IN: pointer to the HDF5 file struct const uint8 *p; IN: the raw information buffer const void *mesg; IN: Pointer to the simple datatype struct RETURNS Non-negative on success/Negative on failure DESCRIPTION This function encodes the native memory form of the attribute message in the "raw" disk form. * * Modifications: * Robb Matzke, 17 Jul 1998 * Added padding for alignment. * * Robb Matzke, 20 Jul 1998 * Added a version number at the beginning. * * Raymond Lu, 8 April 2004 * For data space, changed the operation on H5S_simple_t to * H5S_extent_t * --------------------------------------------------------------------------*/ static herr_t H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) { const H5A_t *attr = (const H5A_t *) mesg; size_t name_len; /* Attribute name length */ unsigned version; /* Attribute version */ hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_encode); /* check args */ assert(f); assert(p); assert(attr); /* Check whether datatype is shared */ if(H5T_committed(attr->dt)) type_shared = TRUE; else type_shared = FALSE; /* Check which version to write out */ if(type_shared) version = H5O_ATTR_VERSION_NEW; /* Write out new version if shared datatype */ else version = H5O_ATTR_VERSION; /* Encode Version */ *p++ = version; /* Set attribute flags if version >1 */ if(version>H5O_ATTR_VERSION) *p++ = (type_shared ? H5O_ATTR_FLAG_TYPE_SHARED : 0 ); /* Set flags for attribute */ else *p++ = 0; /* Reserved, for version <2 */ /* * Encode the lengths of the various parts of the attribute message. The * encoded lengths are exact but we pad each part except the data to be a * multiple of eight bytes (in the first version). */ name_len = HDstrlen(attr->name)+1; UINT16ENCODE(p, name_len); UINT16ENCODE(p, attr->dt_size); UINT16ENCODE(p, attr->ds_size); /* * Write the name including null terminator padded to the correct number * of bytes. */ HDmemcpy(p, attr->name, name_len); HDmemset(p+name_len, 0, H5O_ALIGN(name_len)-name_len); if(version < H5O_ATTR_VERSION_NEW) p += H5O_ALIGN(name_len); else p += name_len; /* encode the attribute datatype */ if(type_shared) { H5O_shared_t sh_mesg; /* Reset shared message information */ HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); /* Get shared message information from datatype */ if ((H5O_MSG_DTYPE->get_share)(f, attr->dt, &sh_mesg/*out*/)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); /* Encode shared message information for datatype */ if((H5O_MSG_SHARED->encode)(f,p,&sh_mesg)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); } /* end if */ else { /* Encode datatype information */ if((H5O_MSG_DTYPE->encode)(f,p,attr->dt)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype"); } /* end else */ if(version < H5O_ATTR_VERSION_NEW) { HDmemset(p+attr->dt_size, 0, H5O_ALIGN(attr->dt_size)-attr->dt_size); p += H5O_ALIGN(attr->dt_size); } /* end if */ else p += attr->dt_size; /* encode the attribute dataspace */ if((H5O_MSG_SDSPACE->encode)(f,p,&(attr->ds->extent))<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace"); if(version < H5O_ATTR_VERSION_NEW) { HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size); p += H5O_ALIGN(attr->ds_size); } /* end if */ else p += attr->ds_size; /* Store attribute data */ if(attr->data) HDmemcpy(p,attr->data,attr->data_size); else HDmemset(p,0,attr->data_size); done: FUNC_LEAVE_NOAPI(ret_value); }
/*-------------------------------------------------------------------------- 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: h5tools_str_sprint * * Purpose: Renders the value pointed to by VP of type TYPE into variable * length string STR. * * Return: A pointer to memory containing the result or NULL on error. * * Programmer: Robb Matzke * Thursday, July 23, 1998 * * Modifications: * Robb Matzke, 1999-04-26 * Made this function safe from overflow problems by allowing it * to reallocate the output string. * * Robb Matzke, 1999-06-04 * Added support for object references. The new `container' * argument is the dataset where the reference came from. * * Robb Matzke, 1999-06-07 * Added support for printing raw data. If info->raw is non-zero * then data is printed in hexadecimal format. * * Robb Matzke, 2003-01-10 * Binary output format is dd:dd:... instead of 0xdddd... so it * doesn't look like a hexadecimal integer, and thus users will * be less likely to complain that HDF5 didn't properly byte * swap their data during type conversion. * * Robb Matzke, LLNL, 2003-06-05 * If TYPE is a variable length string then the pointer to * the value to pring (VP) is a pointer to a `char*'. * * PVN, 28 March 2006 * added H5T_NATIVE_LDOUBLE case *------------------------------------------------------------------------- */ char * h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, hid_t type, void *vp, h5tools_context_t *ctx) { size_t n, offset, size=0, nelmts, start; char *name; unsigned char *ucp_vp = (unsigned char *)vp; char *cp_vp = (char *)vp; hid_t memb, obj, region; unsigned nmembs; static char fmt_llong[8], fmt_ullong[8]; H5T_str_t pad; /* * some tempvars to store the value before we append it to the string to * get rid of the memory alignment problem */ unsigned long long tempullong; long long templlong; unsigned long tempulong; long templong; unsigned int tempuint; int tempint; /* Build default formats for long long types */ if (!fmt_llong[0]) { sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); } /* Append value depending on data type */ start = h5tools_str_len(str); if (info->raw) { size_t i; n = H5Tget_size(type); if (1 == n) { h5tools_str_append(str, OPT(info->fmt_raw, "0x%02x"), ucp_vp[0]); } else { for (i = 0; i < n; i++) { if (i) h5tools_str_append(str, ":"); h5tools_str_append(str, OPT(info->fmt_raw, "%02x"), ucp_vp[i]); } } } else if (H5Tequal(type, H5T_NATIVE_FLOAT)) { float tempfloat; HDmemcpy(&tempfloat, vp, sizeof(float)); h5tools_str_append(str, OPT(info->fmt_float, "%g"), tempfloat); } else if (H5Tequal(type, H5T_NATIVE_DOUBLE)) { double tempdouble; HDmemcpy(&tempdouble, vp, sizeof(double)); h5tools_str_append(str, OPT(info->fmt_double, "%g"), tempdouble); #if H5_SIZEOF_LONG_DOUBLE !=0 } else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) { long double templdouble; HDmemcpy(&templdouble, vp, sizeof(long double)); h5tools_str_append(str, "%Lf", templdouble); #endif } else if (info->ascii && (H5Tequal(type, H5T_NATIVE_SCHAR) || H5Tequal(type, H5T_NATIVE_UCHAR))) { h5tools_print_char(str, info, (char) (*ucp_vp)); } else if (H5T_STRING == H5Tget_class(type)) { unsigned int i; char quote = '\0'; char *s; quote = '\0'; if (H5Tis_variable_str(type)) { /* cp_vp is the pointer into the struct where a `char*' is stored. So we have * to dereference the pointer to get the `char*' to pass to HDstrlen(). */ s = *(char**) cp_vp; if (s != NULL) size = HDstrlen(s); } else { s = cp_vp; size = H5Tget_size(type); } pad = H5Tget_strpad(type); /* Check for NULL pointer for string */ if (s == NULL) { h5tools_str_append(str, "NULL"); } else { for (i = 0; i < size && (s[i] || pad != H5T_STR_NULLTERM); i++) { int j = 1; /* * Count how many times the next character repeats. If the * threshold is zero then that means it can repeat any number * of times. */ if (info->str_repeat > 0) while (i + j < size && s[i] == s[i + j]) j++; /* * Print the opening quote. If the repeat count is high enough to * warrant printing the number of repeats instead of enumerating * the characters, then make sure the character to be repeated is * in it's own quote. */ if (info->str_repeat > 0 && j > info->str_repeat) { if (quote) h5tools_str_append(str, "%c", quote); quote = '\''; h5tools_str_append(str, "%s%c", i ? " " : "", quote); } else if (!quote) { quote = '"'; h5tools_str_append(str, "%s%c", i ? " " : "", quote); } /* Print the character */ h5tools_print_char(str, info, s[i]); /* Print the repeat count */ if (info->str_repeat && j > info->str_repeat) { #ifdef REPEAT_VERBOSE h5tools_str_append(str, "%c repeats %d times", quote, j - 1); #else h5tools_str_append(str, "%c*%d", quote, j - 1); #endif /* REPEAT_VERBOSE */ quote = '\0'; i += j - 1; } } if (quote) h5tools_str_append(str, "%c", quote); if (i == 0) /*empty string*/ h5tools_str_append(str, "\"\""); } /* end else */ } else if (H5Tequal(type, H5T_NATIVE_INT)) { HDmemcpy(&tempint, vp, sizeof(int)); #ifdef H5_HAVE_H5DUMP_PACKED_BITS if(packed_bits_num) tempint = (tempint >> packed_data_offset) & packed_data_mask; #endif h5tools_str_append(str, OPT(info->fmt_int, "%d"), tempint); } else if (H5Tequal(type, H5T_NATIVE_UINT)) {