/* ############################################################################## # # Copyright by The HDF Group. # All rights reserved. # # This file is part of the hl_region High-Level HDF5 APIs. The full copyright # notice, including terms governing use, modification, and redistribution, # is contained in the file COPYING, which can be found at the root of the # source code distribution tree and in the documentation directory (doc/html/). # If you do not have access to this file, you may request a copy of # "the hl_region High-Level HDF5 APIs copyright and license statement" from # help@hdfgroup.org. # ############################################################################## */ /**********************/ /* Module Declaration */ /**********************/ #define hl_region_H5LT_MODULE /***********************/ /* Other Packages Used */ /***********************/ /***********/ /* Headers */ /***********/ #include #include #include #include #include "hl_region_H5LTprivate.h" #include "hl_region_H5LTpkg.h" /* Lite */ /******************/ /* Local Typedefs */ /******************/ /********************/ /* Package Typedefs */ /********************/ #define AT() printf (" at %s:%d in %s()...\n", \ __FILE__, __LINE__, __FUNCTION__); #define H5_FAILED() {puts("*FAILED*");fflush(stdout);} #define TEST_ERROR {H5_FAILED(); AT(); goto error;} /********************/ /* Local Prototypes */ /********************/ /*********************/ /* Package Variables */ /*********************/ /* Package initialization flag */ hbool_t H5_H5LT_init_g = FALSE; /*****************************/ /* Library Private Variables */ /*****************************/ /*******************/ /* Local Variables */ /*******************/ /*------------------------------------------------------------------------- * * internal functions * *------------------------------------------------------------------------- */ /*------------------------------------------------------------------------- * Function: H5LT__pkg_init * * Purpose: Package initialization * * Return: Success: 0, Failure: -1 * * Programmer: Quincey Koziol * * Date: April 14, 2009 * *------------------------------------------------------------------------- */ BEGIN_FUNC(PKGINIT, ERR, herr_t, SUCCEED, FAIL, H5LT__pkg_init(void)) END_FUNC(PKGINIT) /*------------------------------------------------------------------------- * Function: H5LTread_region * * Purpose: Reads selected data to an appication buffer * * Return: FAIL on error, SUCCESS on success * * Programmer: M. Scot Breitenfeld * * Date: February 17, 2009 * * Comments: * * Modifications: * *------------------------------------------------------------------------- */ BEGIN_FUNC(PUB, ERR, herr_t, SUCCEED, FAIL, H5LTread_region(const char *file, const char *path, const hsize_t *block_coord, hid_t mem_type, void *buf)) herr_t status; /* API return status */ hid_t file_id; /* file identifier for the open file */ hid_t dset_id; /* dataset identifier */ hid_t file_space_id; /* identifier of the dataset's dataspace in the file */ hid_t mem_space_id; /* identifier of the memory dataspace */ int ndim; /* the dimensionality of a dataspace */ hsize_t *dims; /* an array of the size of each dimension */ int i; /* counter */ hid_t current_stack_id = -1; /* current error stack id */ /* flags marking state of allocation */ hbool_t dims_alloc = FALSE; /* Open the file */ file_id = H5Fopen(file, H5F_ACC_RDONLY, H5P_DEFAULT); if(file_id < 0) H5E_THROW(H5E_CANTOPENFILE, "H5LT: Failed to open file") /* Open the dataset for a given the path */ dset_id = H5Dopen2(file_id, path, H5P_DEFAULT); if(dset_id < 0) H5E_THROW(H5E_CANTOPENOBJ, "H5LT: Failed to open dataset") /* Get the dataspace of the dataset */ file_space_id = H5Dget_space(dset_id); if(file_space_id < 0) H5E_THROW(H5E_CANTOPENOBJ, "H5LT: Failed to open dataspace") /* Find the rank of the dataspace */ ndim = H5Sget_simple_extent_ndims(file_space_id); if(ndim < 0) H5E_THROW(H5E_NOTFOUND, "H5LT: Failed to find extents of dataspace") /* Allocate space for the dimension array */ dims = (hsize_t *)malloc (sizeof (hsize_t) * ndim); if(dims == NULL) H5E_THROW(H5E_CANTALLOC, "H5LT: Failed to allocate enough memory") dims_alloc = TRUE; /* Find the dimensions of each data space from the block coordinates */ for(i=0; i 0) { status = H5Dclose(dset_id); dset_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataset") } /* end if */ /* Close the file space */ if(file_space_id > 0) { status = H5Sclose(file_space_id); file_space_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LR: Failed to close dataspace") } /* end if */ /* Close the memory space */ if(mem_space_id > 0) { status = H5Sclose(mem_space_id); mem_space_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LR: Failed to close dataspace") } /* end if */ /* Close the file */ if(file_id > 0) { status = H5Fclose(file_id); file_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LR: Failed to close dataset") } /* end if */ /* deallocate arrays */ free(dims); dims_alloc = FALSE; CATCH current_stack_id = H5Eget_current_stack(); if(dims_alloc) free(dims); /* Close the dataspaces */ if(file_space_id > 0) status = H5Sclose(file_space_id); if(mem_space_id > 0) status = H5Sclose(mem_space_id); /* Close the dataset */ if(dset_id > 0) status = H5Dclose(dset_id); /* Close the file */ if(file_id > 0) status = H5Fclose(file_id); status = H5Eset_current_stack(current_stack_id); END_FUNC(PUB) /*------------------------------------------------------------------------- * Function: H5LTcopy_region * * Purpose: Copy data from a specified region in a source dataset to a * specified region in a destination dataset. * * Return: FAIL on error, SUCCESS on success * * Programmer: M. Scot Breitenfeld * * Date: February 17, 2009 * * Comments: * * Modifications: * *------------------------------------------------------------------------- */ BEGIN_FUNC(PUB, ERR, herr_t, SUCCEED, FAIL, H5LTcopy_region(const char *file_src, const char *path_src, const hsize_t *block_coord_src, const char *file_dest, const char *path_dest, const hsize_t *block_coord_dset)) herr_t status; /* API return status */ hsize_t *dims; /* array of the size of each for the destination dimension */ hsize_t *dims_src; /* array of the size of each for the source dimension */ hid_t file_space_id; /* identifier of the dataset's dataspace in the file */ hid_t mem_space_id; /* identifier of the memory dataspace */ hid_t file_id; /* Destination: file ids */ hid_t dset_id; /* Destination: dataset ids */ hid_t type_id; /* Destination: datatype ids */ hid_t fid_src; /* Source: file ids */ hid_t sid_src; /* Source: dataset ids */ hid_t did_src; /* Source: datatype ids */ int ndim; /* the dimensionality of a dataspace */ void *buf; /* buffer to hold data */ hsize_t numelem_src; /* total number of elements in hyperslab */ int nrank_src; /* the dimensionality of the source dataspace */ int i, j; /* counters */ hsize_t *stride; /* hyperslab stride */ hid_t dtype; /* data type of source */ hid_t current_stack_id = -1; /* current error stack id */ /* flags marking state of allocation */ hbool_t dims_src_alloc = FALSE; hbool_t dims_alloc = FALSE; hbool_t buf_alloc = FALSE; hbool_t stride_alloc = FALSE; hbool_t tmp_path_alloc = FALSE; char *tmp_path; hid_t group, gcpl; /* group id for when group does not exist */ size_t size_dtype; /* size of the datatype in bytes */ /* Open the source file */ fid_src = H5Fopen(file_src, H5F_ACC_RDONLY, H5P_DEFAULT); if(fid_src < 0) H5E_THROW(H5E_CANTOPENFILE, "H5LT: Failed to open source file") /* Open the dataset for a given the source path */ did_src = H5Dopen2(fid_src, path_src, H5P_DEFAULT); if(did_src < 0) H5E_THROW(H5E_CANTOPENOBJ, "H5LT: Failed to open dataset for the given path") /* Get the source dataspace of the dataset */ sid_src = H5Dget_space(did_src); if(sid_src < 0) H5E_THROW(H5E_CANTOPENOBJ, "H5LT: Failed to open dataspace") /* Find the rank of the dataspace */ nrank_src = H5Sget_simple_extent_ndims(sid_src); if(nrank_src < 0) H5E_THROW(H5E_NOTFOUND, "H5LT: Failed to find extents of dataspace") /* Allocate space for the dimension array */ dims_src = (hsize_t *)malloc (sizeof (hsize_t) * nrank_src); if(dims_src == NULL) H5E_THROW(H5E_CANTALLOC, "H5LT: Failed to allocate enough memory") dims_src_alloc = TRUE; numelem_src = 1; for(j=0; j 0) { status = H5Dclose(did_src); did_src = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataset") } /* Close the dataspaces */ if(sid_src > 0) { status = H5Sclose(sid_src); sid_src = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataspace") } /* Close the source file */ if(fid_src > 0) { status = H5Fclose(fid_src); fid_src = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataset") } free(dims_src); dims_src_alloc = FALSE; /* Try to create the destination file */ file_id = H5Fcreate(file_dest, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT); /* If file already exists then open it */ if(file_id < 0) { /* Open the destination file */ file_id = H5Fopen(file_dest, H5F_ACC_RDWR, H5P_DEFAULT); if(file_id < 0) H5E_THROW(H5E_CANTOPENFILE, "H5LT: Failed to open destination file") } /* Check if the dataset exists */ if( (dset_id = H5Dopen2(file_id, path_dest, H5P_DEFAULT)) < 0) { /* The dataset does not exist, so: * (1) check to see if the path to the dataset is valid * (a) if it's not then create the path * (2) create the dataset by copying the region specified by * the source path */ /* * find the location of the last "/" in the path */ for(i=0; i 1) { /* Group does not exist so create it */ group = H5Gcreate (file_id, tmp_path, gcpl, H5P_DEFAULT, H5P_DEFAULT); if(group<0) H5E_THROW(H5E_CANTOPENOBJ, "H5LT: Failed to create destination group") status = H5Gclose(group); if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close group") } free(tmp_path); tmp_path_alloc = FALSE; /* create the dataset */ dset_id = H5Dcreate(file_id, path_dest, dtype, mem_space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if(dset_id < 0) H5E_THROW(H5E_CANTOPENOBJ, "H5LT: Failed to create destination dataset") /* write the dataset by essentially doing a straight copy */ status = H5Dwrite(dset_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); if(status < 0) H5E_THROW(H5E_CANTCREATE, "H5LT: Unable to create dataset") if(mem_space_id > 0) { status = H5Sclose(mem_space_id); mem_space_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataspace") } status = H5Pclose(gcpl); if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close property list") } else { if(mem_space_id > 0) { status = H5Sclose(mem_space_id); mem_space_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataspace") } /* Open the dataset for a given the path */ /* Get the dataspace of the dataset */ file_space_id = H5Dget_space(dset_id); if(file_space_id < 0) H5E_THROW(H5E_CANTOPENOBJ, "H5LT: Failed to open dataspace for given path") /* Find the rank of the dataspace */ ndim = H5Sget_simple_extent_ndims(file_space_id); if(ndim < 0) H5E_THROW(H5E_NOTFOUND, "H5LT: Failed to find extents of dataspace") /* Allocate space for the dimension array */ dims = (hsize_t *)malloc (sizeof (hsize_t) * ndim); if(dims == NULL) H5E_THROW(H5E_CANTALLOC, "H5LT: Failed to allocate enough memory") dims_alloc = TRUE; /* find the dimensions of each data space from the block coordinates */ for (i=0; i 0) { status = H5Sclose(file_space_id); file_space_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataspace") } if(mem_space_id > 0) { status = H5Sclose(mem_space_id); mem_space_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataspace") } free(stride); free(dims); stride_alloc = FALSE; dims_alloc = FALSE; } /* Close the dataset */ if(dset_id > 0) { status = H5Dclose(dset_id); dset_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataset") } /* Close datatypes */ if(type_id > 0) { status = H5Tclose(type_id); type_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close datatype") } if(dtype > 0) { status = H5Tclose(dtype); dtype = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close datatype") } /* Close the file */ if(file_id > 0) { status = H5Fclose(file_id); file_id = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataset") } free(buf); buf_alloc = FALSE; CATCH current_stack_id = H5Eget_current_stack(); if(dims_alloc) free(dims); if(buf_alloc) free(buf); if(stride_alloc) free(stride); if(dims_src_alloc) free(dims_src); if(tmp_path_alloc) free(tmp_path); /* Close the dataspace */ if(file_space_id > 0) status = H5Sclose(file_space_id); if(mem_space_id > 0) status = H5Sclose(mem_space_id); /* Close the dataset */ if(dset_id > 0) status = H5Dclose(dset_id); /* Close the file */ if(file_id > 0) status = H5Fclose(file_id); /* Close the datatypes */ if(dtype > 0) status = H5Tclose(dtype); if(type_id > 0) status = H5Tclose(type_id); status = H5Eset_current_stack(current_stack_id); END_FUNC(PUB) /*------------------------------------------------------------------------- * Function: H5LTread_quality_flag * * Purpose: Retrieves the values of quality flags for each element to the * application provided buffer. * * Return: FAIL on error, SUCCESS on success * * Programmer: M. Scot Breitenfeld * * Date: March 30, 2009 * * Comments: * * Modifications: * *------------------------------------------------------------------------- */ BEGIN_FUNC(PUB, ERR, herr_t, SUCCEED, FAIL, H5LTread_bitfield_value(hid_t dset_id, int num_values, const unsigned *offset, const unsigned *lengths, hid_t space_id, int *buf)) herr_t status; /* API return status */ H5S_sel_type sel_type; /* type selection */ hid_t mem_space = -1; /* memory dataspace id */ hsize_t dims[1]; /* array of the size of source dimension, reading into 1D array */ int i, j, icnt; /* counters */ unsigned char *buf_src; /* buffer to read data into from source */ hid_t dtype; /* data type of source */ hid_t current_stack_id = -1; /* current error stack id */ hbool_t buf_src_alloc = FALSE; /* flag marking state of allocation */ /* Determine the type of the dataspace selection */ sel_type = H5Sget_select_type(space_id); /* Get the number of elements */ if(sel_type==H5S_SEL_HYPERSLABS) { dims[0] = H5Sget_select_hyper_nblocks(space_id); } /* end if */ else if(sel_type==H5S_SEL_POINTS) { dims[0] = H5Sget_select_npoints(space_id); } /* end else if */ else if(sel_type==H5S_SEL_NONE) { goto catch_except; } /* end else if */ else if(sel_type==H5S_SEL_ALL) { dims[0] = H5Sget_select_npoints(space_id); } /* end else if */ else H5E_THROW(H5E_BADSELECT, "H5LT: Failed to find selection type") /* Create a new simple dataspace in memory and open it for access */ mem_space = H5Screate_simple (1, dims, NULL); if(mem_space < 0) H5E_THROW(H5E_CANTCREATE, "H5LT: Unable to create dataspace for retrieving elements") buf_src = malloc(sizeof(unsigned char) * dims[0]); if(buf_src == NULL) H5E_THROW(H5E_CANTALLOC, "H5LT: Failed to allocate enough memory") buf_src_alloc = TRUE; dtype = H5Dget_type(dset_id); if(dtype < 0) H5E_THROW(H5E_CANTGET, "H5LT: Unable to determine datatype of dataset") /* Read the region data from the file_space into the mem_space */ status = H5Dread (dset_id, dtype, mem_space, space_id, H5P_DEFAULT, buf_src); if(status < 0) H5E_THROW(H5E_READERROR, "H5LT: Unable to read region data") icnt = 0; for(i=0; i<(int)dims[0]; i++) { for(j=0; j> (offset[j])) & ((1 << lengths[j]) - 1)); icnt += 1; } } /* Close the datatype */ if(dtype > 0) { status = H5Tclose(dtype); dtype = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close datatype") } /* Close the memory space */ if(mem_space > 0) { status = H5Sclose(mem_space); mem_space = -1; if(status < 0) H5E_THROW(H5E_CLOSEERROR, "H5LT: Failed to close dataspace") } free(buf_src); buf_src_alloc = FALSE; CATCH current_stack_id = H5Eget_current_stack(); /* Close */ if(mem_space > 0) status = H5Sclose(mem_space); if(dtype> 0) status = H5Sclose(dtype); if(buf_src_alloc) free(buf_src); status = H5Eset_current_stack(current_stack_id); END_FUNC(PUB)