int_f nh5sget_select_npoints_c ( hid_t_f *space_id , hssize_t_f *npoints ) { int ret_value = 0; hssize_t c_npoints; hid_t c_space_id; c_space_id = *space_id; c_npoints = H5Sget_select_npoints(c_space_id); if ( c_npoints < 0 ) ret_value = -1; *npoints = (hssize_t_f)c_npoints; return ret_value; }
int_f h5dread_vl_real_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, real_f *buf, hsize_t_f *dims, size_t_f *len) /******/ { int ret_value = -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; herr_t status; size_t max_len; hvl_t *c_buf; hsize_t i; hssize_t num_elem; 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; c_xfer_prp = (hid_t)*xfer_prp; max_len = (size_t)dims[0]; num_elem = H5Sget_select_npoints(c_mem_space_id); if(num_elem != (hssize_t)dims[1]) return ret_value; c_buf = (hvl_t *)HDmalloc((size_t)num_elem * sizeof(hvl_t)); if (c_buf == NULL) return ret_value; /* * Call H5Dread function. */ status = H5Dread(c_dset_id, c_mem_type_id, c_mem_space_id, c_file_space_id, c_xfer_prp, c_buf); if ( status <0 ) goto DONE; for (i=0; i < (hsize_t)num_elem; i++) { len[i] = (size_t_f)c_buf[i].len; memcpy(&buf[i*max_len], c_buf[i].p, c_buf[i].len*sizeof(real_f)); } H5Dvlen_reclaim(c_mem_type_id, c_mem_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: HDfree(c_buf); return ret_value; }
int_f h5dvlen_get_max_len_c ( hid_t_f *dset_id , hid_t_f *type_id, hid_t_f *space_id, size_t_f *len) /******/ { int ret_value = -1; size_t c_len; hid_t c_dset_id; hid_t c_type_id; hid_t c_space_id; hvl_t *c_buf; int i; hssize_t num_elem; herr_t status; c_dset_id = (hid_t)*dset_id; c_type_id = (hid_t)*type_id; c_space_id = (hid_t)*space_id; num_elem = H5Sget_select_npoints(c_space_id); if( num_elem < 0) return ret_value; c_buf = (hvl_t *)HDmalloc(sizeof(hvl_t)*(size_t)num_elem); if (c_buf == NULL) return ret_value; status = H5Dread(c_dset_id, c_type_id, H5S_ALL, c_space_id, H5P_DEFAULT, c_buf); if(status < 0) goto DONE; c_len = 0; for (i=0; i < num_elem; i++) c_len = H5_MAX(c_len, c_buf[i].len); *len = (size_t_f)c_len; H5Dvlen_reclaim(c_type_id, c_space_id, H5P_DEFAULT, c_buf); ret_value = 0; DONE: HDfree(c_buf); return ret_value; }
void* load_H5_Data_4D(const char* filename, int datatype, const char* datasetname, int W, int H, int D, int ox, int oy, int oz, int timestep, int comp, bool fit) { // fprintf(stderr, "%s:%s()\n", __FILE__, __func__); //only handle h5 data with one component for now assert(comp == 1); hid_t input_file = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); if (input_file < 0) { fprintf(stderr, "%s:%s(): Error opening input file %s\n", __FILE__, __func__, filename); exit(1); } hid_t dataset = H5Dopen(input_file, datasetname); if (dataset < 0) { H5Eprint(NULL); H5Fclose(input_file); fprintf(stderr, "Error opening dataset on file %s\n", filename); //throw IOException(string("Error opening dataset")); exit(1); } hid_t dataspace = H5Dget_space(dataset); assert(dataspace >=0); hsize_t maxdims[4]; hsize_t dims[4]; int dimensions = H5Sget_simple_extent_dims(dataspace, dims, maxdims); assert (dimensions == 4); #ifdef _DEBUG fprintf(stderr, "data dimension(%d, %d, %d, %d)\n", (int)dims[0], (int)dims[1], (int)dims[2], (int)dims[3]); fprintf(stderr, "origin(%d,%d,%d,%d), count(%d,%d,%d,%d)\n", ox, oy, oz, timestep, W, H, D, 1); if(fit) fprintf(stderr, "read data to fit\n"); #endif hsize_t start[4]; hsize_t start_out[4]; hsize_t stride[4]; hsize_t stride_out[4]; hsize_t count[4]; hsize_t count_out[4]; hsize_t block[4]; hsize_t block_out[4]; start[0] = timestep; start_out[0] = 0; start[1] = oz; start_out[1] = 0; start[2] = oy; start_out[2] = 0; start[3] = ox; start_out[3] = 0; stride[0] = 1; stride_out[0] = 1; stride[1] = fit? dims[0]/D : 1; stride_out[1] = 1; stride[2] = fit? dims[1]/H : 1; stride_out[2] = 1; stride[3] = fit? dims[2]/W : 1; stride_out[3] = 1; count[0] = 1; count_out[0] = count[0]; count[1] = D; count_out[1] = count[1]; count[2] = H; count_out[2] = count[2]; count[3] = W; count_out[3] = count[3]; block[0] = 1; block_out[0] = 1; block[1] = 1; block_out[1] = 1; block[2] = 1; block_out[2] = 1; block[3] = 1; block_out[3] = 1; herr_t status; status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, stride, count, block); int b = get_depth(datatype); size_t my_val = count[0] * count[1] * count[2] * count[3] * b; //printf("set to read %ld bytes data\n", my_val); assert(H5Sget_select_npoints(dataspace) * b == my_val); //allocate the output buffer void *wholedata = malloc(my_val); if(wholedata == NULL) { fprintf(stderr, "can't allocate output buffer\n"); exit(1); } if ( status < 0 ) { H5Eprint(NULL); fprintf(stderr, "Cannot select data slab\n"); //throw IOException("Cannot select data slab"); exit(1); } hid_t memspace = H5Screate_simple(4, count_out, NULL); status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start_out , stride_out, count_out, block_out); if ( status < 0 ) { H5Eprint(NULL); fprintf(stderr, "Cannot select mem slab\n"); //throw IOException("Cannot select mem slab"); exit(1); } assert(H5Sget_select_npoints(memspace) * b == my_val); hid_t plist = H5Pcreate(H5P_DATASET_XFER); //is this hint really useful? status = H5Pset_buffer(plist, my_val, NULL, NULL); if ( status < 0 ) { H5Eprint(NULL); fprintf(stderr, "Cannot set data buffer\n"); //throw IOException("Cannot set buffer"); exit(1); } //read data into "data" buffer, fortran ordering! hid_t mem_type; switch(datatype) { case 0: mem_type = H5T_NATIVE_CHAR; break; case 1: mem_type = H5T_NATIVE_SHORT; break; case 2: mem_type = H5T_NATIVE_FLOAT; break; //H5T_IEEE_F32LE case 3: mem_type = H5T_NATIVE_DOUBLE; break; default: mem_type = H5T_NATIVE_CHAR; } status = H5Dread (dataset, mem_type, memspace, dataspace, plist, wholedata); if ( status < 0 ) { H5Eprint(NULL); fprintf(stderr, "READ ERROR!\n"); //throw IOException("Read error"); exit(1); } H5Pclose (plist); H5Sclose (memspace); H5Sclose( dataspace ); H5Dclose( dataset ); H5Fclose( input_file ); return wholedata; }
int main(void) { hid_t fid1; /* HDF5 File IDs */ hid_t dset1, /* Dataset ID */ dset2; /* Dereferenced dataset ID */ hid_t sid1, /* Dataspace ID #1 */ sid2; /* Dataspace ID #2 */ hsize_t * coords; /* Coordinate buffer */ hsize_t low[SPACE2_RANK]; /* Selection bounds */ hsize_t high[SPACE2_RANK]; /* Selection bounds */ hdset_reg_ref_t *rbuf; /* buffer to to read disk */ int *drbuf; /* Buffer for reading numeric data from disk */ int i, j; /* counting variables */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ /* Allocate write & read buffers */ rbuf=malloc(sizeof(hdset_reg_ref_t)*SPACE1_DIM1); drbuf=calloc(sizeof(int),SPACE2_DIM1*SPACE2_DIM2); /* Open the file */ fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT); /* Open the dataset */ dset1=H5Dopen(fid1,"/Dataset1"); /* Read selection from disk */ ret=H5Dread(dset1,H5T_STD_REF_DSETREG,H5S_ALL,H5S_ALL,H5P_DEFAULT,rbuf); /* Try to open objects */ dset2 = H5Rdereference(dset1,H5R_DATASET_REGION,&rbuf[0]); /* Check information in referenced dataset */ sid1 = H5Dget_space(dset2); ret=H5Sget_simple_extent_npoints(sid1); printf(" Number of elements in the dataset is : %d\n",ret); /* Read from disk */ ret=H5Dread(dset2,H5T_NATIVE_INT,H5S_ALL,H5S_ALL,H5P_DEFAULT,drbuf); for(i=0; i<SPACE2_DIM1; i++) { for (j=0; j<SPACE2_DIM2; j++) printf (" %d ", drbuf[i*SPACE2_DIM2+j]); printf("\n"); } /* Get the hyperslab selection */ sid2=H5Rget_region(dset1,H5R_DATASET_REGION,&rbuf[0]); /* Verify correct hyperslab selected */ ret = H5Sget_select_npoints(sid2); printf(" Number of elements in the hyperslab is : %d \n", ret); ret = H5Sget_select_hyper_nblocks(sid2); coords=malloc(ret*SPACE2_RANK*sizeof(hsize_t)*2); /* allocate space for the hyperslab blocks */ ret = H5Sget_select_hyper_blocklist(sid2,0,ret,coords); printf(" Hyperslab coordinates are : \n"); printf (" ( %lu , %lu ) ( %lu , %lu ) \n", \ (unsigned long)coords[0],(unsigned long)coords[1],(unsigned long)coords[2],(unsigned long)coords[3]); free(coords); ret = H5Sget_select_bounds(sid2,low,high); /* Close region space */ ret = H5Sclose(sid2); /* Get the element selection */ sid2=H5Rget_region(dset1,H5R_DATASET_REGION,&rbuf[1]); /* Verify correct elements selected */ ret = H5Sget_select_elem_npoints(sid2); printf(" Number of selected elements is : %d\n", ret); /* Allocate space for the element points */ coords= malloc(ret*SPACE2_RANK*sizeof(hsize_t)); ret = H5Sget_select_elem_pointlist(sid2,0,ret,coords); printf(" Coordinates of selected elements are : \n"); for (i=0; i<2*NPOINTS; i=i+2) printf(" ( %lu , %lu ) \n", (unsigned long)coords[i],(unsigned long)coords[i+1]); free(coords); ret = H5Sget_select_bounds(sid2,low,high); /* Close region space */ ret = H5Sclose(sid2); /* Close first space */ ret = H5Sclose(sid1); /* Close dereferenced Dataset */ ret = H5Dclose(dset2); /* Close Dataset */ ret = H5Dclose(dset1); /* Close file */ ret = H5Fclose(fid1); /* Free memory buffers */ free(rbuf); free(drbuf); return 0; }
int main (void) { hid_t file, space, memspace, dset, dset2, attr; /* Handles */ herr_t status; hsize_t dims[1] = {DIM0}, dims2[2] = {DS2DIM0, DS2DIM1}, coords[4][2] = { {0, 1}, {2, 11}, {1, 0}, {2, 4} }, start[2] = {0, 0}, stride[2] = {2, 11}, count[2] = {2, 2}, block[2] = {1, 3}; hssize_t npoints; hdset_reg_ref_t wdata[DIM0], /* Write buffer */ *rdata; /* Read buffer */ ssize_t size; char wdata2[DS2DIM0][DS2DIM1] = {"The quick brown", "fox jumps over ", "the 5 lazy dogs"}, *rdata2, *name; int ndims, i; /* * Create a new file using the default properties. */ file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); /* * Create a dataset with character data. */ space = H5Screate_simple (2, dims2, NULL); dset2 = H5Dcreate (file, DATASET2, H5T_STD_I8LE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Dwrite (dset2, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata2); /* * Create reference to a list of elements in dset2. */ status = H5Sselect_elements (space, H5S_SELECT_SET, 4, coords[0]); status = H5Rcreate (&wdata[0], file, DATASET2, H5R_DATASET_REGION, space); /* * Create reference to a hyperslab in dset2, close dataspace. */ status = H5Sselect_hyperslab (space, H5S_SELECT_SET, start, stride, count, block); status = H5Rcreate (&wdata[1], file, DATASET2, H5R_DATASET_REGION, space); status = H5Sclose (space); /* * Create dataset with a null dataspace to serve as the parent for * the attribute. */ space = H5Screate (H5S_NULL); dset = H5Dcreate (file, DATASET, H5T_STD_I32LE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); status = H5Sclose (space); /* * Create dataspace. Setting maximum size to NULL sets the maximum * size to be the current size. */ space = H5Screate_simple (1, dims, NULL); /* * Create the attribute and write the region references to it. */ attr = H5Acreate (dset, ATTRIBUTE, H5T_STD_REF_DSETREG, space, H5P_DEFAULT, H5P_DEFAULT); status = H5Awrite (attr, H5T_STD_REF_DSETREG, wdata); /* * Close and release resources. */ status = H5Aclose (attr); status = H5Dclose (dset); status = H5Dclose (dset2); status = H5Sclose (space); status = H5Fclose (file); /* * Now we begin the read section of this example. Here we assume * the attribute has the same name and rank, but can have any size. * Therefore we must allocate a new array to read in data using * malloc(). */ /* * Open file, dataset, and attribute. */ file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); dset = H5Dopen (file, DATASET, H5P_DEFAULT); attr = H5Aopen (dset, ATTRIBUTE, H5P_DEFAULT); /* * Get dataspace and allocate memory for read buffer. */ space = H5Aget_space (attr); ndims = H5Sget_simple_extent_dims (space, dims, NULL); rdata = (hdset_reg_ref_t *) malloc (dims[0] * sizeof (hdset_reg_ref_t)); status = H5Sclose (space); /* * Read the data. */ status = H5Aread (attr, H5T_STD_REF_DSETREG, rdata); /* * Output the data to the screen. */ for (i=0; i<dims[0]; i++) { printf ("%s[%d]:\n ->", ATTRIBUTE, i); /* * Open the referenced object, retrieve its region as a * dataspace selection. */ dset2 = H5Rdereference (dset, H5P_DEFAULT, H5R_DATASET_REGION, &rdata[i]); space = H5Rget_region (dset, H5R_DATASET_REGION, &rdata[i]); /* * Get the length of the object's name, allocate space, then * retrieve the name. */ size = 1 + H5Iget_name (dset2, NULL, 0); name = (char *) malloc (size); size = H5Iget_name (dset2, name, size); /* * Allocate space for the read buffer. We will only allocate * enough space for the selection, plus a null terminator. The * read buffer will be 1-dimensional. */ npoints = H5Sget_select_npoints (space); rdata2 = (char *) malloc (npoints + 1); /* * Read the dataset region, and add a null terminator so we can * print it as a string. */ memspace = H5Screate_simple (1, (hsize_t *) &npoints, NULL); status = H5Dread (dset2, H5T_NATIVE_CHAR, memspace, space, H5P_DEFAULT, rdata2); rdata2[npoints] = '\0'; /* * Print the name and region data, close and release resources. */ printf (" %s: %s\n", name, rdata2); free (rdata2); free (name); status = H5Sclose (space); status = H5Sclose (memspace); status = H5Dclose (dset2); } /* * Close and release resources. */ free (rdata); status = H5Aclose (attr); status = H5Dclose (dset); status = H5Fclose (file); return 0; }
virtual dataset_length_t get_element_count() { return H5Sget_select_npoints(win_sel_handle); }
/*------------------------------------------------------------------------- * Function: H5LD_get_dset_elmts * * Purpose: To retrieve selected data from the dataset * * Return: Success: 0 * Failure: negative * * Programmer: Vailin Choi; August 2010 * *------------------------------------------------------------------------- */ static herr_t H5LD_get_dset_elmts(hid_t did, const hsize_t *prev_dims, const hsize_t *cur_dims, const char *fields, void *buf) { hid_t dtid = -1, tid = -1; /* Dataset type id */ hid_t sid = -1, mid = -1; /* Dataspace and memory space id */ hssize_t snum_elmts; /* Number of dataset elements in the selection (signed) */ hsize_t num_elmts; /* Number of dataset elements in the selection */ hsize_t start[H5S_MAX_RANK];/* Starting offset */ hsize_t count[H5S_MAX_RANK];/* ??offset */ H5LD_memb_t **listv = NULL; /* Vector for storing information in "fields" */ char *dup_fields = NULL; /* A copy of "fields" */ char *sav_buf = NULL; /* Saved pointer temporary buffer */ unsigned ctr; /* Counter for # of curr_dims > prev_dims */ int ndims; /* Number of dimensions for the dataset */ int i; /* Local index variable */ herr_t ret_value = FAIL; /* Return value */ /* Verify parameters */ if(prev_dims == NULL || cur_dims == NULL || buf == NULL) goto done; /* Get dataset's dataspace */ if((sid = H5Dget_space(did)) < 0) goto done; /* Get the number of dimensions */ if((ndims = H5Sget_simple_extent_ndims(sid)) < 0) goto done; /* Verify that cur_dims must have one dimension whose size is greater than prev_dims */ HDmemset(start, 0, sizeof start); HDmemset(count, 0, sizeof count); ctr = 0; for(i = 0; i < ndims; i++) if(cur_dims[i] > prev_dims[i]) { ++ctr; count[i] = cur_dims[i] - prev_dims[i]; start[i] = prev_dims[i]; } /* end if */ else { /* < or = */ start[i] = 0; count[i] = MIN(prev_dims[i], cur_dims[i]); } /* end else */ if(!ctr) goto done; if(ctr == 1) { /* changes for only one dimension */ /* Make the selection in the dataset based on "cur_dims" and "prev_dims" */ if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL, count, NULL) < 0) goto done; } /* end if */ else { /* changes for more than one dimensions */ HDmemset(start, 0, sizeof start); /* Make the selection in the dataset based on "cur_dims" and "prev_dims" */ if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL, cur_dims, NULL) < 0) goto done; if(H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, NULL, prev_dims, NULL) < 0) goto done; } /* end else */ /* Get the number of elements in the selection */ if(0 == (snum_elmts = H5Sget_select_npoints(sid))) goto done; num_elmts = (hsize_t)snum_elmts; /* Create the memory space for the selection */ if((mid = H5Screate_simple(1, &num_elmts, NULL)) < 0) goto done; /* Get the native datatype size */ if((dtid = H5Dget_type(did)) < 0) goto done; if((tid = H5Tget_native_type(dtid, H5T_DIR_DEFAULT)) < 0) goto done; if(fields == NULL) { /* nothing in "fields" */ /* Read and store all the elements in "buf" */ if(H5Dread(did, tid, mid, sid, H5P_DEFAULT, buf) < 0) goto done; } /* end if */ else { /* "fields" is specified */ unsigned char *buf_p = (unsigned char *)buf; /* Pointer to the destination buffer */ char *tmp_buf; /* Temporary buffer for data read */ size_t tot_tsize; /* Total datatype size */ size_t len; /* Estimate the number of comma-separated fields in "fields" */ /* should be a compound datatype if "fields" exists */ if(H5Tget_class(tid) != H5T_COMPOUND) goto done; /* Get the total size of the dataset's datatypes */ if(0 == (tot_tsize = H5LD_get_dset_type_size(did, NULL))) goto done; /* Allocate memory for reading in the elements in the dataset selection */ if(NULL == (sav_buf = tmp_buf = (char *)HDcalloc((size_t)num_elmts, tot_tsize))) goto done; /* Read the dataset elements in the selection */ if(H5Dread(did, tid, mid, sid, H5P_DEFAULT, tmp_buf) < 0) goto done; /* Make a copy of "fields" */ if(NULL == (dup_fields = HDstrdup(fields))) goto done; /* Allocate memory for the vector of H5LD_memb_t pointers */ len = (HDstrlen(fields) / 2) + 2; if(NULL == (listv = (H5LD_memb_t **)HDcalloc(len, sizeof(H5LD_memb_t *)))) goto done; /* Process and store information for "fields" */ if(H5LD_construct_vector(dup_fields, listv, tid) < 0) goto done; /* Copy data for each dataset element in the selection */ for(i = 0; i < (int)num_elmts; i++) { int j; /* Local index variable */ /* Copy data for "fields" to the input buffer */ for(j = 0; listv[j] != NULL; j++) { HDmemcpy(buf_p, tmp_buf + listv[j]->tot_offset, listv[j]->last_tsize); buf_p += listv[j]->last_tsize; } /* end for */ tmp_buf += tot_tsize; } /* end for */ /* Clean up the vector of H5LD_memb_t structures */ H5LD_clean_vector(listv); } /* end else */ /* Indicate success */ ret_value = SUCCEED; done: H5E_BEGIN_TRY H5Tclose(dtid); H5Tclose(tid); H5Sclose(sid); H5Sclose(mid); H5E_END_TRY /* Free the array of H5LD_memb_t pointers */ if(listv) HDfree(listv); /* Free memory */ if(dup_fields) HDfree(dup_fields); if(sav_buf) HDfree(sav_buf); return(ret_value); } /* H5LD_get_dset_elmts() */
escdf_errno_t utils_hdf5_read_dataset(hid_t dtset_id, void *buf, hid_t mem_type_id, const hsize_t *start, const hsize_t *count, const hsize_t *stride) { hid_t memspace_id, diskspace_id, plist; herr_t err_id; hssize_t len; /* disk use the start, count and stride. */ if ((diskspace_id = H5Dget_space(dtset_id)) < 0) { RETURN_WITH_ERROR(diskspace_id); } if (start && count) { if ((err_id = H5Sselect_hyperslab(diskspace_id, H5S_SELECT_SET, start, stride, count, NULL)) < 0) { H5Sclose(diskspace_id); RETURN_WITH_ERROR(err_id); } } else { if ((err_id = H5Sselect_all(diskspace_id)) < 0) { H5Sclose(diskspace_id); RETURN_WITH_ERROR(err_id); } } if ((len = H5Sget_select_npoints(diskspace_id)) < 0) { H5Sclose(diskspace_id); RETURN_WITH_ERROR(len); } if (!len) { if ((err_id = H5Sselect_none(diskspace_id)) < 0) { H5Sclose(diskspace_id); RETURN_WITH_ERROR(err_id); } } /* create dataspace for memory and disk. */ /* memory is a flat array with the size on the slice. */ if ((memspace_id = H5Screate_simple(1, &len, NULL)) < 0) { H5Sclose(diskspace_id); RETURN_WITH_ERROR(memspace_id); } /* Read */ plist = H5Pcreate(H5P_DATASET_XFER); /* H5Pset_dxpl_mpio(plist, H5FD_MPIO_COLLECTIVE); */ if ((err_id = H5Dread(dtset_id, mem_type_id, memspace_id, diskspace_id, plist, buf)) < 0) { H5Pclose(plist); H5Sclose(diskspace_id); H5Sclose(memspace_id); RETURN_WITH_ERROR(err_id); } H5Pclose(plist); H5Sclose(diskspace_id); H5Sclose(memspace_id); return ESCDF_SUCCESS; }
/*------------------------------------------------------------------------- * Function: H5DOappend() * * Purpose: To append elements to a dataset. * * axis: the dataset dimension (zero-based) for the append * extension: the # of elements to append for the axis-th dimension * memtype: the datatype * buf: buffer with data for the append * * Return: Non-negative on success/Negative on failure * * Programmer: Vailin Choi; Jan 2014 * * Note: * This routine is copied from the fast forward feature branch: features/hdf5_ff * src/H5FF.c:H5DOappend() with the following modifications: * 1) Remove and replace macro calls such as * FUNC_ENTER_API, H5TRACE, HGOTO_ERROR * accordingly because hl does not have these macros * 2) Replace H5I_get_type() by H5Iget_type() * 3) Replace H5P_isa_class() by H5Pisa_class() * 4) Fix a bug in the following: replace extension by size[axis] * if(extension < old_size) { * ret_value = FAIL; * goto done; * } * *------------------------------------------------------------------------- */ herr_t H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, hid_t memtype, const void *buf) { hbool_t created_dxpl = FALSE; /* Whether we created a DXPL */ hsize_t size[H5S_MAX_RANK]; /* The new size (after extension */ hsize_t old_size = 0; /* The size of the dimension to be extended */ int sndims; /* Number of dimensions in dataspace (signed) */ unsigned ndims; /* Number of dimensions in dataspace */ hid_t space_id = FAIL; /* Old file space */ hid_t new_space_id = FAIL; /* New file space (after extension) */ hid_t mem_space_id = FAIL; /* Memory space for data buffer */ hssize_t snelmts; /* Number of elements in selection (signed) */ hsize_t nelmts; /* Number of elements in selection */ hid_t dapl = FAIL; /* Dataset access property list */ hsize_t start[H5S_MAX_RANK]; /* H5Sselect_Hyperslab: starting offset */ hsize_t count[H5S_MAX_RANK]; /* H5Sselect_hyperslab: # of blocks to select */ hsize_t stride[H5S_MAX_RANK]; /* H5Sselect_hyperslab: # of elements to move when selecting */ hsize_t block[H5S_MAX_RANK]; /* H5Sselect_hyperslab: # of elements in a block */ hsize_t *boundary = NULL; /* Boundary set in append flush property */ H5D_append_cb_t append_cb; /* Callback function set in append flush property */ void *udata; /* User data set in append flush property */ hbool_t hit = FALSE; /* Boundary is hit or not */ hsize_t k; /* Local index variable */ unsigned u; /* Local index variable */ herr_t ret_value = FAIL; /* Return value */ /* check arguments */ if(H5I_DATASET != H5Iget_type(dset_id)) goto done; /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */ if(H5P_DEFAULT == dxpl_id) { if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) goto done; created_dxpl = TRUE; } /* end if */ else if(TRUE != H5Pisa_class(dxpl_id, H5P_DATASET_XFER)) goto done; /* Get the dataspace of the dataset */ if(FAIL == (space_id = H5Dget_space(dset_id))) goto done; /* Get the rank of this dataspace */ if((sndims = H5Sget_simple_extent_ndims(space_id)) < 0) goto done; ndims = (unsigned)sndims; /* Verify correct axis */ if(axis >= ndims) goto done; /* Get the dimensions sizes of the dataspace */ if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0) goto done; /* Adjust the dimension size of the requested dimension, * but first record the old dimension size */ old_size = size[axis]; size[axis] += extension; if(size[axis] < old_size) goto done; /* Set the extent of the dataset to the new dimension */ if(H5Dset_extent(dset_id, size) < 0) goto done; /* Get the new dataspace of the dataset */ if(FAIL == (new_space_id = H5Dget_space(dset_id))) goto done; /* Select a hyperslab corresponding to the append operation */ for(u = 0 ; u < ndims ; u++) { start[u] = 0; stride[u] = 1; count[u] = size[u]; block[u] = 1; if(u == axis) { count[u] = extension; start[u] = old_size; } /* end if */ } /* end for */ if(FAIL == H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, start, stride, count, block)) goto done; /* The # of elemnts in the new extended dataspace */ if((snelmts = H5Sget_select_npoints(new_space_id)) < 0) goto done; nelmts = (hsize_t)snelmts; /* create a memory space */ if(FAIL == (mem_space_id = H5Screate_simple(1, &nelmts, NULL))) goto done; /* Write the data */ if(H5Dwrite(dset_id, memtype, mem_space_id, new_space_id, dxpl_id, buf) < 0) goto done; /* Obtain the dataset's access property list */ if((dapl = H5Dget_access_plist(dset_id)) < 0) goto done; /* Allocate the boundary array */ boundary = (hsize_t *)HDmalloc(ndims * sizeof(hsize_t)); /* Retrieve the append flush property */ if(H5Pget_append_flush(dapl, ndims, boundary, &append_cb, &udata) < 0) goto done; /* No boundary for this axis */ if(boundary[axis] != 0) { /* Determine whether a boundary is hit or not */ for(k = start[axis]; k < size[axis]; k++) if(!((k + 1) % boundary[axis])) { hit = TRUE; break; } if(hit) { /* Hit the boundary */ /* Invoke callback if there is one */ if(append_cb && append_cb(dset_id, size, udata) < 0) goto done; /* Do a dataset flush */ if(H5Dflush(dset_id) < 0) goto done; } /* end if */ } /* end if */ /* Indicate success */ ret_value = SUCCEED; done: /* Close dxpl if we created it vs. one was passed in */ if(created_dxpl) { if(H5Pclose(dxpl_id) < 0) ret_value = FAIL; } /* end if */ /* Close old dataspace */ if(space_id != FAIL && H5Sclose(space_id) < 0) ret_value = FAIL; /* Close new dataspace */ if(new_space_id != FAIL && H5Sclose(new_space_id) < 0) ret_value = FAIL; /* Close memory dataspace */ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0) ret_value = FAIL; /* Close the dataset access property list */ if(dapl != FAIL && H5Pclose(dapl) < 0) ret_value = FAIL; if(boundary) HDfree(boundary); return ret_value; } /* H5DOappend() */