diff options
Diffstat (limited to 'src/H5Dio.c')
-rw-r--r-- | src/H5Dio.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c index 285451e..b7c2ecb 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -291,6 +291,19 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, H5D_io_info_t io_info; /* Dataset I/O info */ H5D_type_info_t type_info; /* Datatype info for operation */ hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */ + H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */ + /* projection of the supplied mem_space to a new */ + /* data space with rank equal to that of */ + /* file_space. */ + /* */ + /* This field is only used if */ + /* H5S_select_shape_same() returns TRUE when */ + /* comparing the mem_space and the data_space, */ + /* and the mem_space have different rank. */ + /* */ + /* Note that if this variable is used, the */ + /* projected mem space must be discarded at the */ + /* end of the function to avoid a memory leak. */ H5D_storage_t store; /*union of EFL and chunk pointer in file space */ hssize_t snelmts; /*total number of elmts (signed) */ hsize_t nelmts; /*total number of elmts */ @@ -340,6 +353,37 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, if(!(H5S_has_extent(mem_space))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set") + /* H5S_select_shape_same() has been modified to accept topologically identical + * selections with different rank as having the same shape (if the most + * rapidly changing coordinates match up), but the I/O code still has + * difficulties with the notion. + * + * To solve this, we check to see if H5S_select_shape_same() returns true, + * and if the ranks of the mem and file spaces are different. If the are, + * construct a new mem space that is equivalent to the old mem space, and + * use that instead. + * + * Note that in general, this requires us to touch up the memory buffer as + * well. + */ + if(TRUE == H5S_select_shape_same(mem_space, file_space) && + H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { + void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ + /* to the beginning of the projected mem space. */ + + /* Attempt to construct projected dataspace for memory dataspace */ + if(H5S_select_construct_projection(mem_space, &projected_mem_space, + (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.dst_type_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") + HDassert(projected_mem_space); + HDassert(adj_buf); + + /* Switch to using projected memory dataspace & adjusted buffer */ + mem_space = projected_mem_space; + buf = adj_buf; + } /* end if */ + + /* Retrieve dataset properties */ /* <none needed in the general case> */ @@ -417,6 +461,11 @@ done: if(type_info_init && H5D_typeinfo_term(&type_info) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info") + /* discard projected mem space if it was created */ + if(NULL != projected_mem_space) + if(H5S_close(projected_mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace") + FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) } /* end H5D_read() */ @@ -442,6 +491,19 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, H5D_io_info_t io_info; /* Dataset I/O info */ H5D_type_info_t type_info; /* Datatype info for operation */ hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */ + H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */ + /* projection of the supplied mem_space to a new */ + /* data space with rank equal to that of */ + /* file_space. */ + /* */ + /* This field is only used if */ + /* H5S_select_shape_same() returns TRUE when */ + /* comparing the mem_space and the data_space, */ + /* and the mem_space have different rank. */ + /* */ + /* Note that if this variable is used, the */ + /* projected mem space must be discarded at the */ + /* end of the function to avoid a memory leak. */ H5D_storage_t store; /*union of EFL and chunk pointer in file space */ hssize_t snelmts; /*total number of elmts (signed) */ hsize_t nelmts; /*total number of elmts */ @@ -515,6 +577,37 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, file_space = dataset->shared->space; if(!mem_space) mem_space = file_space; + + /* H5S_select_shape_same() has been modified to accept topologically + * identical selections with different rank as having the same shape + * (if the most rapidly changing coordinates match up), but the I/O + * code still has difficulties with the notion. + * + * To solve this, we check to see if H5S_select_shape_same() returns + * true, and if the ranks of the mem and file spaces are different. + * If the are, construct a new mem space that is equivalent to the + * old mem space, and use that instead. + * + * Note that in general, this requires us to touch up the memory buffer + * as well. + */ + if(TRUE == H5S_select_shape_same(mem_space, file_space) && + H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { + void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ + /* to the beginning of the projected mem space. */ + + /* Attempt to construct projected dataspace for memory dataspace */ + if(H5S_select_construct_projection(mem_space, &projected_mem_space, + (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.src_type_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") + HDassert(projected_mem_space); + HDassert(adj_buf); + + /* Switch to using projected memory dataspace & adjusted buffer */ + mem_space = projected_mem_space; + buf = adj_buf; + } /* end if */ + if((snelmts = H5S_GET_SELECT_NPOINTS(mem_space)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection") H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, hsize_t); @@ -608,6 +701,11 @@ done: if(type_info_init && H5D_typeinfo_term(&type_info) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info") + /* discard projected mem space if it was created */ + if(NULL != projected_mem_space) + if(H5S_close(projected_mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace") + FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) } /* end H5D_write() */ |