From 21b8d65c2c53e4c1392ae63d120741914a3467a6 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Tue, 12 Jul 2022 10:46:26 -0500 Subject: 1.12 HDFFV-11310 implement JNI VL support for primitive types (#1856) * HDFFV-11310 - implement VL read/write using List of Lists * Fix function name typo * Add JIRA issue * Correct note to match change in code. * HDFFV-11318 add VL references as byte arrays * Fix unreleased allocations * Fix format --- config/sanitizer/code-coverage.cmake | 10 +- java/src/hdf/hdf5lib/H5.java | 27 +- java/src/hdf/hdf5lib/HDF5Constants.java | 65 ++- java/src/jni/h5aImp.c | 818 ++++++++++++++++++++++++++------ java/src/jni/h5aImp.h | 18 +- java/src/jni/h5dImp.c | 805 ++++++++++++++++++++++--------- java/src/jni/h5dImp.h | 4 +- java/src/jni/h5util.c | 451 +++++++++++++----- java/src/jni/h5util.h | 2 + java/src/jni/nativeData.c | 3 +- java/test/TestH5A.java | 243 +++++++++- java/test/TestH5D.java | 221 ++++++++- java/test/TestH5R.java | 469 ++++++++++++++++++ java/test/testfiles/JUnit-TestH5A.txt | 3 +- java/test/testfiles/JUnit-TestH5D.txt | 5 +- java/test/testfiles/JUnit-TestH5R.txt | 4 +- release_docs/RELEASE.txt | 40 +- tools/lib/h5tools_str.c | 92 +++- tools/lib/h5tools_str.h | 1 + 19 files changed, 2710 insertions(+), 571 deletions(-) diff --git a/config/sanitizer/code-coverage.cmake b/config/sanitizer/code-coverage.cmake index e71bfd7..3a99024 100644 --- a/config/sanitizer/code-coverage.cmake +++ b/config/sanitizer/code-coverage.cmake @@ -214,7 +214,7 @@ function(target_code_coverage TARGET_NAME) # Add code coverage instrumentation to the target's linker command if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") target_compile_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate - -fcoverage-mapping) + -fcoverage-mapping --coverage) set_property( TARGET ${TARGET_NAME} APPEND_STRING @@ -225,7 +225,7 @@ function(target_code_coverage TARGET_NAME) PROPERTY LINK_FLAGS "-fcoverage-mapping ") elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") target_compile_options(${TARGET_NAME} PRIVATE -fprofile-arcs - -ftest-coverage) + -ftest-coverage --coverage) target_link_libraries(${TARGET_NAME} PRIVATE gcov) endif() @@ -413,10 +413,10 @@ endfunction() # use `target_code_coverage`. function(add_code_coverage) if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") - add_compile_options(-fprofile-instr-generate -fcoverage-mapping) - add_link_options(-fprofile-instr-generate -fcoverage-mapping) + add_compile_options(-fprofile-instr-generate -fcoverage-mapping --coverage) + add_link_options(-fprofile-instr-generate -fcoverage-mapping --coverage) elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") - add_compile_options(-fprofile-arcs -ftest-coverage) + add_compile_options(-fprofile-arcs -ftest-coverage --coverage) link_libraries(gcov) endif() endfunction() diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index 133cd2c..c2be6ca 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -1242,6 +1242,10 @@ public class H5 implements java.io.Serializable { log.trace("H5Aread_string type"); status = H5Aread_string(attr_id, mem_type_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5AreadVL type"); + status = H5AreadVL(attr_id, mem_type_id, (Object[])obj); + } else { // Create a data buffer to hold the data into a Java Array HDFArray theArray = new HDFArray(obj); @@ -1788,6 +1792,10 @@ public class H5 implements java.io.Serializable { log.trace("H5Dwrite_string type"); status = H5Awrite_string(attr_id, mem_type_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5AwriteVL type"); + status = H5AwriteVL(attr_id, mem_type_id, (Object[])obj); + } else { HDFArray theArray = new HDFArray(obj); byte[] buf = theArray.byteify(); @@ -2772,6 +2780,11 @@ public class H5 implements java.io.Serializable { status = H5Dread_string(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5DreadVL type"); + status = + H5DreadVL(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, (Object[])obj); + } else { // Create a data buffer to hold the data into a Java Array HDFArray theArray = new HDFArray(obj); @@ -3450,6 +3463,11 @@ public class H5 implements java.io.Serializable { status = H5Dwrite_string(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, (String[])obj); } + else if (H5.H5Tget_class(mem_type_id) == HDF5Constants.H5T_VLEN) { + log.trace("H5DwriteVL type"); + status = H5DwriteVL(dataset_id, mem_type_id, mem_space_id, file_space_id, xfer_plist_id, + (Object[])obj); + } else { HDFArray theArray = new HDFArray(obj); byte[] buf = theArray.byteify(); @@ -9356,9 +9374,8 @@ public class H5 implements java.io.Serializable { byte[] buf = theArray.emptyBytes(); int status = H5Pget_fill_value(plist_id, type_id, buf); - if (status >= 0) { + if (status >= 0) obj = theArray.arrayify(buf); - } return status; } @@ -11018,8 +11035,6 @@ public class H5 implements java.io.Serializable { public synchronized static native void H5Rdestroy(byte[] ref_ptr) throws HDF5LibraryException, NullPointerException, IllegalArgumentException; - // Info // - /** * H5Rget_type retrieves the type of a reference. * @@ -11076,8 +11091,6 @@ public class H5 implements java.io.Serializable { public synchronized static native byte[] H5Rcopy(byte[] src_ref_ptr) throws HDF5LibraryException, NullPointerException, IllegalArgumentException; - // Dereference // - /** * H5Ropen_object opens that object and returns an identifier. * The object opened with this function should be closed when it is no longer needed @@ -11224,8 +11237,6 @@ public class H5 implements java.io.Serializable { public synchronized static native int H5Rget_obj_type3(byte[] ref_ptr, long rapl_id) throws HDF5LibraryException, NullPointerException, IllegalArgumentException; - // Get name // - /** * H5Rget_file_name retrieves the file name for the object, region or attribute reference pointed to. * diff --git a/java/src/hdf/hdf5lib/HDF5Constants.java b/java/src/hdf/hdf5lib/HDF5Constants.java index 1b85c1f..2f5ec91 100644 --- a/java/src/hdf/hdf5lib/HDF5Constants.java +++ b/java/src/hdf/hdf5lib/HDF5Constants.java @@ -16,7 +16,7 @@ package hdf.hdf5lib; import hdf.hdf5lib.structs.H5O_token_t; /** - * /** This class contains C constants and enumerated types of HDF5 library. The + * This class contains C constants and enumerated types of HDF5 library. The * values of these constants are obtained from the library by calling J2C(int * jconstant), where jconstant is any of the private constants which start their * name with "JH5" need to be converted. @@ -62,31 +62,62 @@ public class HDF5Constants { public static final int H5_ITER_NATIVE = H5_ITER_NATIVE(); /** Common iteration orders, Number of iteration orders */ public static final int H5_ITER_N = H5_ITER_N(); - /** */ + /** The version of the H5AC_cache_config_t in use */ public static final int H5AC_CURR_CACHE_CONFIG_VERSION = H5AC_CURR_CACHE_CONFIG_VERSION(); - /** */ + /** The maximum length of the trace file path */ public static final int H5AC_MAX_TRACE_FILE_NAME_LEN = H5AC_MAX_TRACE_FILE_NAME_LEN(); - /** */ + /** + * When metadata_write_strategy is set to this value, only process + * zero is allowed to write dirty metadata to disk. All other + * processes must retain dirty metadata until they are informed at + * a sync point that the dirty metadata in question has been written + * to disk. + */ public static final int H5AC_METADATA_WRITE_STRATEGY_PROCESS_ZERO_ONLY = H5AC_METADATA_WRITE_STRATEGY_PROCESS_ZERO_ONLY(); - /** */ + /** + * In the distributed metadata write strategy, process zero still makes + * the decisions as to what entries should be flushed, but the actual + * flushes are distributed across the processes in the computation to + * the extent possible. + */ public static final int H5AC_METADATA_WRITE_STRATEGY_DISTRIBUTED = H5AC_METADATA_WRITE_STRATEGY_DISTRIBUTED(); - /** */ + /** Don't attempt to increase the size of the cache automatically */ public static final int H5C_incr_off = H5C_incr_off(); - /** */ + /** + * Attempt to increase the size of the cache + * whenever the average hit rate over the last epoch drops + * below the value supplied in the lower_hr_threshold + * field + */ public static final int H5C_incr_threshold = H5C_incr_threshold(); - /** */ + /** Don't perform flash increases in the size of the cache */ public static final int H5C_flash_incr_off = H5C_flash_incr_off(); - /** */ + /** increase the current maximum cache size by x * flash_multiple less any free space in the cache */ public static final int H5C_flash_incr_add_space = H5C_flash_incr_add_space(); - /** */ + /** Don't attempt to decrease the size of the cache automatically */ public static final int H5C_decr_off = H5C_decr_off(); - /** */ + /** + * Attempt to decrease the size of the cache + * whenever the average hit rate over the last epoch rises + * above the value supplied in the upper_hr_threshold + * field + */ public static final int H5C_decr_threshold = H5C_decr_threshold(); - /** */ + /** + * At the end of each epoch, search the cache for + * entries that have not been accessed for at least the number + * of epochs specified in the epochs_before_eviction field, and + * evict these entries + */ public static final int H5C_decr_age_out = H5C_decr_age_out(); - /** */ + /** + * Same as age_out, but we only + * attempt to reduce the cache size when the hit rate observed + * over the last epoch exceeds the value provided in the + * upper_hr_threshold field + */ public static final int H5C_decr_age_out_with_threshold = H5C_decr_age_out_with_threshold(); /** */ public static final int H5D_CHUNK_IDX_BTREE = H5D_CHUNK_IDX_BTREE(); @@ -910,11 +941,11 @@ public class HDF5Constants { /** */ public static final int H5R_MAXTYPE = H5R_MAXTYPE(); /** */ - public static final int H5R_REF_BUF_SIZE = H5R_REF_BUF_SIZE(); + public static final int H5R_DSET_REG_REF_BUF_SIZE = H5R_DSET_REG_REF_BUF_SIZE(); /** */ public static final int H5R_OBJ_REF_BUF_SIZE = H5R_OBJ_REF_BUF_SIZE(); /** */ - public static final int H5R_DSET_REG_REF_BUF_SIZE = H5R_DSET_REG_REF_BUF_SIZE(); + public static final int H5R_REF_BUF_SIZE = H5R_REF_BUF_SIZE(); /** */ public static final int H5R_OBJECT = H5R_OBJECT(); /** */ @@ -2393,11 +2424,11 @@ public class HDF5Constants { private static native final int H5R_MAXTYPE(); - private static native final int H5R_REF_BUF_SIZE(); + private static native final int H5R_DSET_REG_REF_BUF_SIZE(); private static native final int H5R_OBJ_REF_BUF_SIZE(); - private static native final int H5R_DSET_REG_REF_BUF_SIZE(); + private static native final int H5R_REF_BUF_SIZE(); private static native final int H5R_OBJECT(); diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index 6bf86d0..32bae07 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -56,7 +56,7 @@ static herr_t H5A_iterate_cb(hid_t g_id, const char *name, const H5A_info_t *inf /* * Class: hdf_hdf5lib_H5 - * Method: H5Acreate + * Method: _H5Acreate * Signature: (JLjava/lang/String;JJJ)J */ JNIEXPORT jlong JNICALL @@ -86,7 +86,7 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_name + * Method: _H5Aopen_name * Signature: (JLjava/lang/String;)J */ JNIEXPORT jlong JNICALL @@ -124,7 +124,7 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_idx + * Method: _H5Aopen_idx * Signature: (JI)J */ JNIEXPORT jlong JNICALL @@ -158,7 +158,10 @@ Java_hdf_hdf5lib_H5_H5Aread(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_t { jboolean readBufIsCopy; jbyte * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -166,18 +169,20 @@ Java_hdf_hdf5lib_H5_H5Aread(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_t if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -187,11 +192,17 @@ Java_hdf_hdf5lib_H5_H5Aread(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_t PIN_BYTE_ARRAY(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Aread: read buffer not pinned"); } - if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, readBuf)) < 0) + if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, (void *)readBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -214,7 +225,10 @@ Java_hdf_hdf5lib_H5_H5Awrite(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_ { jboolean writeBufIsCopy; jbyte * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -222,18 +236,18 @@ Java_hdf_hdf5lib_H5_H5Awrite(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_ if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -248,6 +262,9 @@ Java_hdf_hdf5lib_H5_H5Awrite(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_ done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -270,7 +287,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1short(JNIEnv *env, jclass clss, jlong attr_id, jlon { jboolean readBufIsCopy; jshort * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -278,18 +298,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1short(JNIEnv *env, jclass clss, jlong attr_id, jlon if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_short: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_short: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_short: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -304,6 +326,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1short(JNIEnv *env, jclass clss, jlong attr_id, jlon done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -326,7 +354,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1short(JNIEnv *env, jclass clss, jlong attr_id, jlo { jboolean writeBufIsCopy; jshort * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -334,18 +365,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1short(JNIEnv *env, jclass clss, jlong attr_id, jlo if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_short: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_short: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_short: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -360,6 +391,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1short(JNIEnv *env, jclass clss, jlong attr_id, jlo done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -381,27 +415,32 @@ Java_hdf_hdf5lib_H5_H5Aread_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jint * readBuf = NULL; - herr_t status = FAIL; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (buf == NULL) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_int: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_int: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_int: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -416,6 +455,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -438,7 +483,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong { jboolean writeBufIsCopy; jint * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -446,18 +494,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong if (buf == NULL) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_int: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_int: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_int: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -472,6 +520,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1int(JNIEnv *env, jclass clss, jlong attr_id, jlong done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -494,7 +545,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1long(JNIEnv *env, jclass clss, jlong attr_id, jlong { jboolean readBufIsCopy; jlong * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -502,18 +556,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1long(JNIEnv *env, jclass clss, jlong attr_id, jlong if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_long: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_long: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_long: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -528,6 +584,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1long(JNIEnv *env, jclass clss, jlong attr_id, jlong done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -550,7 +612,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1long(JNIEnv *env, jclass clss, jlong attr_id, jlon { jboolean writeBufIsCopy; jlong * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -558,18 +623,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1long(JNIEnv *env, jclass clss, jlong attr_id, jlon if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_long: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_long: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_long: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -584,6 +649,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1long(JNIEnv *env, jclass clss, jlong attr_id, jlon done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -606,7 +674,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1float(JNIEnv *env, jclass clss, jlong attr_id, jlon { jboolean readBufIsCopy; jfloat * readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -614,18 +685,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1float(JNIEnv *env, jclass clss, jlong attr_id, jlon if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_float: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_float: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_float: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -640,6 +713,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1float(JNIEnv *env, jclass clss, jlong attr_id, jlon done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -662,7 +741,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1float(JNIEnv *env, jclass clss, jlong attr_id, jlo { jboolean writeBufIsCopy; jfloat * writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -670,18 +752,18 @@ Java_hdf_hdf5lib_H5_H5Awrite_1float(JNIEnv *env, jclass clss, jlong attr_id, jlo if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_float: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_float: variable length type not supported"); + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_float: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -696,6 +778,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1float(JNIEnv *env, jclass clss, jlong attr_id, jlo done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -718,7 +803,10 @@ Java_hdf_hdf5lib_H5_H5Aread_1double(JNIEnv *env, jclass clss, jlong attr_id, jlo { jboolean readBufIsCopy; jdouble *readBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -726,18 +814,20 @@ Java_hdf_hdf5lib_H5_H5Aread_1double(JNIEnv *env, jclass clss, jlong attr_id, jlo if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_double: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_double: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_double: variable length type not supported"); + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, @@ -752,6 +842,12 @@ Java_hdf_hdf5lib_H5_H5Aread_1double(JNIEnv *env, jclass clss, jlong attr_id, jlo done: if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -774,7 +870,10 @@ Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *env, jclass clss, jlong attr_id, jl { jboolean writeBufIsCopy; jdouble *writeBuf = NULL; - htri_t data_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -782,18 +881,17 @@ Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *env, jclass clss, jlong attr_id, jl if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: variable length type not supported"); + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: buf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Awrite_double: variable length type not supported"); + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -808,6 +906,9 @@ Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *env, jclass clss, jlong attr_id, jl done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -958,12 +1059,456 @@ done: /* * Class: hdf_hdf5lib_H5 * Method: H5AreadVL - * Signature: (JJ[Ljava/lang/String;)I + * Signature: (JJ[java/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) { H5T_class_t type_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean readBufIsCopy; + jbyteArray *readBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AreadVL: read buffer is NULL"); + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (vl_data_class) { + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } + + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadVL: failed to allocate raw VL read buffer"); + + if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, (void *)rawBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cBool, "valueOf", "(Z)Ljava/lang/Boolean;"); + jmethodID byteValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cByte, "valueOf", "(B)Ljava/lang/Byte;"); + jmethodID shortValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cShort, "valueOf", "(S)Ljava/lang/Short;"); + jmethodID intValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cInt, "valueOf", "(I)Ljava/lang/Integer;"); + jmethodID longValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cLong, "valueOf", "(J)Ljava/lang/Long;"); + jmethodID floatValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cFloat, "valueOf", "(F)Ljava/lang/Float;"); + jmethodID doubleValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cDouble, "valueOf", "(D)Ljava/lang/Double;"); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + jmethodID addMethod = ENVPTR->GetMethodID(ENVONLY, cList, "add", "(Ljava/lang/Object;)Z"); + + /* Convert each element to a list */ + for (i = 0; i < (size_t)n; i++) { + // The list we're going to return: + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cp_vp = (char *)rawBuf + i * typeSize; + /* Get the number of sequence elements */ + jsize nelmts = ((hvl_t *)cp_vp)->len; + + jobject jobj = NULL; + for (j = 0; j < nelmts; j++) { + switch (vlClass) { + /* case H5T_BOOL: { + jboolean boolValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&boolValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j*vlSize+x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cBool, boolValueMid, boolValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&byteValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cByte, byteValueMid, byteValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jshort): { + jshort shortValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&shortValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cShort, shortValueMid, + shortValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jint): { + jint intValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&intValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cInt, intValueMid, intValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jlong): { + jlong longValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&longValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cLong, longValueMid, longValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&floatValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cFloat, floatValueMid, + floatValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jdouble): { + jdouble doubleValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&doubleValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cDouble, doubleValueMid, + doubleValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_REFERENCE: { + jboolean bb; + jbyte * barray = NULL; + if (NULL == (jobj = ENVPTR->NewByteArray(ENVONLY, vlSize))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, &bb, + "readVL reference: byte array not pinned"); + + for (x = 0; x < (int)vlSize; x++) { + barray[x] = ((jbyte *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, jobj ? 0 : JNI_ABORT); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5AreadVL: invalid class type"); + break; + } + + // Add it to the list + ENVPTR->CallBooleanMethod(ENVONLY, jList, addMethod, jobj); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + } /* end for */ + + if (rawBuf) + HDfree(rawBuf); + } + else { + if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, (void *)readBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (readBuf) { + if ((status >= 0) && vl_data_class) { + H5Treclaim(attr_id, sid, H5P_DEFAULT, readBuf); + if (sid >= 0) + H5Sclose(sid); + } + + UNPIN_BYTE_ARRAY(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5AreadVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5AwriteVL + * Signature: (JJ[java/util/ArrayList;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) +{ + H5T_class_t type_class; + hsize_t dims[H5S_MAX_RANK]; + hid_t sid = H5I_INVALID_HID; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean writeBufIsCopy; + jbyteArray *writeBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AwriteVL: write buffer is NULL"); + + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5AwriteVL: readBuf length < 0"); + } + + dims[0] = (hsize_t)n; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL: failed to allocate raw VL write buffer"); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = ENVPTR->GetMethodID(ENVONLY, cBool, "booleanValue", "()Z"); + jmethodID byteValueMid = ENVPTR->GetMethodID(ENVONLY, cByte, "byteValue", "()B"); + jmethodID shortValueMid = ENVPTR->GetMethodID(ENVONLY, cShort, "shortValue", "()S"); + jmethodID intValueMid = ENVPTR->GetMethodID(ENVONLY, cInt, "intValue", "()I"); + jmethodID longValueMid = ENVPTR->GetMethodID(ENVONLY, cLong, "longValue", "()J"); + jmethodID floatValueMid = ENVPTR->GetMethodID(ENVONLY, cFloat, "floatValue", "()F"); + jmethodID doubleValueMid = ENVPTR->GetMethodID(ENVONLY, cDouble, "doubleValue", "()D"); + + /* Convert each list to a vlen element */ + for (i = 0; i < (size_t)n; i++) { + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + + // retrieve the toArray method and invoke it + jmethodID mToArray = ENVPTR->GetMethodID(ENVONLY, cList, "toArray", "()[Ljava/lang/Object;"); + if (mToArray == NULL) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, jList, mToArray); + jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array); + + cp_vp = (char *)rawBuf + i * typeSize; + ((hvl_t *)cp_vp)->len = jnelmts; + + if (NULL == (((hvl_t *)cp_vp)->p = HDmalloc(jnelmts * vlSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL: failed to allocate vlen ptr buffer"); + + jobject jobj = NULL; + for (j = 0; j < (int)jnelmts; j++) { + if (NULL == (jobj = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)array, (jsize)j))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + switch (vlClass) { + /* case H5T_BOOL: { + jboolean boolValue = ENVPTR->CallBooleanMethod(ENVONLY, jobj, boolValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&boolValue)[x]; + } + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue = ENVPTR->CallByteMethod(ENVONLY, jobj, byteValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&byteValue)[x]; + } + break; + } + case sizeof(jshort): { + jshort shortValue = ENVPTR->CallShortMethod(ENVONLY, jobj, shortValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&shortValue)[x]; + } + break; + } + case sizeof(jint): { + jint intValue = ENVPTR->CallIntMethod(ENVONLY, jobj, intValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&intValue)[x]; + } + break; + } + case sizeof(jlong): { + jlong longValue = ENVPTR->CallLongMethod(ENVONLY, jobj, longValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&longValue)[x]; + } + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue = ENVPTR->CallFloatMethod(ENVONLY, jobj, floatValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&floatValue)[x]; + } + break; + } + case sizeof(jdouble): { + jdouble doubleValue = ENVPTR->CallDoubleMethod(ENVONLY, jobj, doubleValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&doubleValue)[x]; + } + break; + } + } + break; + } + case H5T_REFERENCE: { + jbyte *barray = (jbyte *)ENVPTR->GetByteArrayElements(ENVONLY, jobj, 0); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)barray)[x]; + } + ENVPTR->ReleaseByteArrayElements(ENVONLY, jobj, barray, 0); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5AwriteVL: invalid class type"); + break; + } + ENVPTR->DeleteLocalRef(ENVONLY, jobj); + } + ENVPTR->DeleteLocalRef(ENVONLY, jList); + } /* end for (i = 0; i < n; i++) */ + + if ((status = H5Awrite((hid_t)attr_id, (hid_t)mem_type_id, rawBuf)) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (rawBuf) + HDfree(rawBuf); + } + else { + PIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5AwriteVL: write buffer not pinned"); + if ((status = H5Awrite((hid_t)attr_id, (hid_t)mem_type_id, writeBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(attr_id, sid, H5P_DEFAULT, writeBuf); + + if (type_class != H5T_VLEN) + UNPIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5AwriteVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Aread_VLStrings + * Signature: (JJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Aread_1VLStrings(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, + jobjectArray buf) +{ + H5T_class_t type_class; htri_t isStr = 0; htri_t isVlenStr = 0; htri_t isComplex = 0; @@ -974,7 +1519,7 @@ Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AreadVL: read buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aread_VLStrings: read buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1024,7 +1569,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Aread_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Aread_1VLStrings */ /* * Helper method to read in a buffer of variable-length strings from an HDF5 @@ -1160,11 +1705,12 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5AwriteVL + * Method: H5Awrite_VLStrings * Signature: (JJ[Ljava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) +Java_hdf_hdf5lib_H5_H5Awrite_1VLStrings(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, + jobjectArray buf) { H5T_class_t type_class; htri_t isStr = 0; @@ -1177,7 +1723,7 @@ Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong me UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5AwriteVL: write buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Awrite_VLStrings: write buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1227,7 +1773,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Awrite_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Awrite_1VLStrings */ /* * Helper method to convert an array of Java strings into a buffer of C-strings. @@ -1273,7 +1819,7 @@ H5AwriteVL_str(JNIEnv *env, hid_t aid, hid_t tid, jobjectArray buf) if (NULL == (writeBuf[i] = (char *)HDmalloc((size_t)length + 1))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_str: failed to allocate string buffer"); - HDstrncpy(writeBuf[i], utf8, (size_t)length); + HDstrncpy(writeBuf[i], utf8, (size_t)length + 1); writeBuf[i][length] = '\0'; UNPIN_JAVA_STRING(ENVONLY, obj, utf8); @@ -1297,8 +1843,8 @@ done: HDfree(writeBuf); } - return (jint)status; -} + return status; +} /* end H5AwriteVL_str */ /* * Helper method to convert an array of Java strings into a buffer of @@ -1385,7 +1931,7 @@ done: H5Sclose(sid); return status; -} /* end H5AwriteVL_str */ +} /* end H5AwriteVL_asstr */ /* * Class: hdf_hdf5lib_H5 diff --git a/java/src/jni/h5aImp.h b/java/src/jni/h5aImp.h index aee0e40..094f990 100644 --- a/java/src/jni/h5aImp.h +++ b/java/src/jni/h5aImp.h @@ -22,7 +22,7 @@ extern "C" { /* * Class: hdf_hdf5lib_H5 - * Method: H5Acreate + * Method: _H5Acreate * Signature: (JLjava/lang/String;JJJ)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Acreate(JNIEnv *, jclass, jlong, jstring, jlong, jlong, @@ -30,14 +30,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Acreate(JNIEnv *, jclass, jlong, /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_name + * Method: _H5Aopen_name * Signature: (JLjava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aopen_1name(JNIEnv *, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Aopen_idx + * Method: _H5Aopen_idx * Signature: (JI)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aopen_1idx(JNIEnv *, jclass, jlong, jint); @@ -137,14 +137,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Awrite_1double(JNIEnv *, jclass, jl /* * Class: hdf_hdf5lib_H5 * Method: H5AreadVL - * Signature: (JJ[Ljava/lang/String;)I + * Signature: (JJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *, jclass, jlong, jlong, jobjectArray); /* * Class: hdf_hdf5lib_H5 * Method: H5AwriteVL - * Signature: (JJ[Ljava/lang/String;)I + * Signature: (JJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *, jclass, jlong, jlong, jobjectArray); @@ -185,14 +185,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Aread_1reg_1ref(JNIEnv *, jclass, j /* * Class: hdf_hdf5lib_H5 - * Method: H5Aget_space + * Method: _H5Aget_space * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aget_1space(JNIEnv *, jclass, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Aget_type + * Method: _H5Aget_type * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aget_1type(JNIEnv *, jclass, jlong); @@ -220,7 +220,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Adelete(JNIEnv *, jclass, jlong, js /* * Class: hdf_hdf5lib_H5 - * Method: H5Aclose + * Method: _H5Aclose * Signature: (J)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5__1H5Aclose(JNIEnv *, jclass, jlong); @@ -350,7 +350,7 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aopen_1by_1name(JNIEnv *, jclass /* * Class: hdf_hdf5lib_H5 - * Method: H5Aget_create_plist + * Method: _H5Aget_create_plist * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Aget_1create_1plist(JNIEnv *, jclass, jlong); diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index 73b252a..a20bb6c 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -183,28 +183,24 @@ Java_hdf_hdf5lib_H5_H5Dread(JNIEnv *env, jclass clss, jlong dataset_id, jlong me jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jbyte * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: variable length type not supported"); - if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread: read buffer not critically pinned"); @@ -219,6 +215,9 @@ Java_hdf_hdf5lib_H5_H5Dread(JNIEnv *env, jclass clss, jlong dataset_id, jlong me done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -241,28 +240,24 @@ Java_hdf_hdf5lib_H5_H5Dwrite(JNIEnv *env, jclass clss, jlong dataset_id, jlong m jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jbyte * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite: variable length type not supported"); - if (isCriticalPinning) { PIN_BYTE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite: write buffer not critically pinned"); @@ -277,6 +272,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite(JNIEnv *env, jclass clss, jlong dataset_id, jlong m done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -383,7 +381,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1short(JNIEnv *env, jclass clss, jlong dataset_id, j { jboolean readBufIsCopy; jshort * readBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -391,19 +389,15 @@ Java_hdf_hdf5lib_H5_H5Dread_1short(JNIEnv *env, jclass clss, jlong dataset_id, j if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_short: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_short: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_short: variable length type not supported"); - if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_short: read buffer not critically pinned"); @@ -418,6 +412,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1short(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -441,7 +438,7 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1short(JNIEnv *env, jclass clss, jlong dataset_id, { jboolean writeBufIsCopy; jshort * writeBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -449,19 +446,15 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1short(JNIEnv *env, jclass clss, jlong dataset_id, if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_short: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_short: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_short: variable length type not supported"); - if (isCriticalPinning) { PIN_SHORT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_short: write buffer not critically pinned"); @@ -476,6 +469,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1short(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -498,28 +494,24 @@ Java_hdf_hdf5lib_H5_H5Dread_1int(JNIEnv *env, jclass clss, jlong dataset_id, jlo jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jint * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_int: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_int: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_int: variable length type not supported"); - if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_int: read buffer not critically pinned"); @@ -534,6 +526,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1int(JNIEnv *env, jclass clss, jlong dataset_id, jlo done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -556,28 +551,24 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1int(JNIEnv *env, jclass clss, jlong dataset_id, jl jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jint * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_int: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_int: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_int: variable length type not supported"); - if (isCriticalPinning) { PIN_INT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_int: write buffer not critically pinned"); @@ -592,6 +583,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1int(JNIEnv *env, jclass clss, jlong dataset_id, jl done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -614,28 +608,24 @@ Java_hdf_hdf5lib_H5_H5Dread_1long(JNIEnv *env, jclass clss, jlong dataset_id, jl jlongArray buf, jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jlong * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_long: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_long: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_long: variable length type not supported"); - if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_long: read buffer not critically pinned"); @@ -650,6 +640,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1long(JNIEnv *env, jclass clss, jlong dataset_id, jl done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -672,28 +665,24 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1long(JNIEnv *env, jclass clss, jlong dataset_id, j jlongArray buf, jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jlong * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_long: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_long: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_long: variable length type not supported"); - if (isCriticalPinning) { PIN_LONG_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_long: write buffer not critically pinned"); @@ -708,6 +697,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1long(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -730,28 +722,24 @@ Java_hdf_hdf5lib_H5_H5Dread_1float(JNIEnv *env, jclass clss, jlong dataset_id, j jfloatArray buf, jboolean isCriticalPinning) { jboolean readBufIsCopy; - htri_t data_class; jfloat * readBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_float: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_float: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_float: variable length type not supported"); - if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_float: read buffer not critically pinned"); @@ -766,6 +754,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1float(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -788,27 +779,23 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1float(JNIEnv *env, jclass clss, jlong dataset_id, jfloatArray buf, jboolean isCriticalPinning) { jboolean writeBufIsCopy; - htri_t data_class; jfloat * writeBuf = NULL; - herr_t status = FAIL; + htri_t vl_data_class; + herr_t status = FAIL; UNUSED(clss); if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_float: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_float: variable length type not supported"); - - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_float: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread: readBuf length < 0"); + } if (isCriticalPinning) { PIN_FLOAT_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, @@ -824,6 +811,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1float(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -847,7 +837,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1double(JNIEnv *env, jclass clss, jlong dataset_id, { jboolean readBufIsCopy; jdouble *readBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -855,19 +845,15 @@ Java_hdf_hdf5lib_H5_H5Dread_1double(JNIEnv *env, jclass clss, jlong dataset_id, if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_double: read buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_double: variable length type not supported"); + /* Get size of data array */ + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread: readBuf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_double: variable length type not supported"); - if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, readBuf, &readBufIsCopy, "H5Dread_double: read buffer not critically pinned"); @@ -882,6 +868,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1double(JNIEnv *env, jclass clss, jlong dataset_id, done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -905,7 +894,7 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *env, jclass clss, jlong dataset_id, { jboolean writeBufIsCopy; jdouble *writeBuf = NULL; - htri_t data_class; + htri_t vl_data_class; herr_t status = FAIL; UNUSED(clss); @@ -913,19 +902,14 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *env, jclass clss, jlong dataset_id, if (NULL == buf) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: write buffer is NULL"); - if ((data_class = H5Tdetect_class(mem_type_id, H5T_VLEN)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: variable length type not supported"); + if (ENVPTR->GetArrayLength(ENVONLY, buf) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: buf length < 0"); + } - /* Recursively detect any vlen string in type (compound, array ...) */ - if ((data_class = H5Tdetect_variable_str(mem_type_id)) < 0) + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); - if (data_class) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_double: variable length type not supported"); - if (isCriticalPinning) { PIN_DOUBLE_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5Dwrite_double: write buffer not critically pinned"); @@ -940,6 +924,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -1094,13 +1081,445 @@ done: /* * Class: hdf_hdf5lib_H5 * Method: H5DreadVL - * Signature: (JJJJJ[Ljava/lang/String;)I + * Signature: (JJJJJ[java/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) { H5T_class_t type_class; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean readBufIsCopy; + jbyteArray *readBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DreadVL: read buffer is NULL"); + + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5DreadVL: readBuf length < 0"); + } + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DreadVL: failed to allocate raw VL read buffer"); + + if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, (void *)rawBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cBool, "valueOf", "(Z)Ljava/lang/Boolean;"); + jmethodID byteValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cByte, "valueOf", "(B)Ljava/lang/Byte;"); + jmethodID shortValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cShort, "valueOf", "(S)Ljava/lang/Short;"); + jmethodID intValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cInt, "valueOf", "(I)Ljava/lang/Integer;"); + jmethodID longValueMid = ENVPTR->GetStaticMethodID(ENVONLY, cLong, "valueOf", "(J)Ljava/lang/Long;"); + jmethodID floatValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cFloat, "valueOf", "(F)Ljava/lang/Float;"); + jmethodID doubleValueMid = + ENVPTR->GetStaticMethodID(ENVONLY, cDouble, "valueOf", "(D)Ljava/lang/Double;"); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + jmethodID addMethod = ENVPTR->GetMethodID(ENVONLY, cList, "add", "(Ljava/lang/Object;)Z"); + + /* Convert each element to a list */ + for (i = 0; i < (size_t)n; i++) { + // The list we're going to return: + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cp_vp = (char *)rawBuf + i * typeSize; + /* Get the number of sequence elements */ + jsize nelmts = ((hvl_t *)cp_vp)->len; + + jobject jobj = NULL; + for (j = 0; j < nelmts; j++) { + switch (vlClass) { + /*case H5T_BOOL: { + jboolean boolValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&boolValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j*vlSize+x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cBool, boolValueMid, boolValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&byteValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cByte, byteValueMid, byteValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jshort): { + jshort shortValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&shortValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cShort, shortValueMid, + shortValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jint): { + jint intValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&intValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cInt, intValueMid, intValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jlong): { + jlong longValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&longValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = + ENVPTR->CallStaticObjectMethod(ENVONLY, cLong, longValueMid, longValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&floatValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cFloat, floatValueMid, + floatValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + case sizeof(jdouble): { + jdouble doubleValue; + for (x = 0; x < (int)vlSize; x++) { + ((char *)&doubleValue)[x] = ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + + jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cDouble, doubleValueMid, + doubleValue); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + } + break; + } + case H5T_REFERENCE: { + jboolean bb; + jbyte * barray = NULL; + if (NULL == (jobj = ENVPTR->NewByteArray(ENVONLY, vlSize))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, &bb, + "readVL reference: byte array not pinned"); + + for (x = 0; x < (int)vlSize; x++) { + barray[x] = ((jbyte *)((hvl_t *)cp_vp)->p)[j * vlSize + x]; + } + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, jobj ? 0 : JNI_ABORT); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5DreadVL: invalid class type"); + break; + } + + // Add it to the list + ENVPTR->CallBooleanMethod(ENVONLY, jList, addMethod, jobj); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + } /* end for */ + + if (rawBuf) + HDfree(rawBuf); + } + else { + if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, (void *)readBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + + UNPIN_BYTE_ARRAY(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5DreadVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5DwriteVL + * Signature: (JJJJJ[java/util/ArrayList;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, + jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) +{ + H5T_class_t type_class; + jsize n; + htri_t vl_data_class; + herr_t status = FAIL; + jboolean writeBufIsCopy; + jbyteArray *writeBuf = NULL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DwriteVL: write buffer is NULL"); + + /* Get size of data array */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5DwriteVL: readBuf length < 0"); + } + + if ((vl_data_class = h5str_detect_vlen(mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (type_class == H5T_VLEN) { + size_t typeSize; + hid_t memb = H5I_INVALID_HID; + H5T_class_t vlClass; + size_t vlSize; + void * rawBuf = NULL; + jobject * jList = NULL; + + size_t i, j, x; + char * cp_vp = NULL; + + if (!(typeSize = H5Tget_size(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(memb = H5Tget_super(mem_type_id))) + H5_LIBRARY_ERROR(ENVONLY); + if ((vlClass = H5Tget_class((hid_t)memb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(vlSize = H5Tget_size(memb))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (rawBuf = HDcalloc((size_t)n, typeSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DwriteVL: failed to allocate raw VL write buffer"); + + /* Cache class types */ + jclass cBool = ENVPTR->FindClass(ENVONLY, "java/lang/Boolean"); + jclass cByte = ENVPTR->FindClass(ENVONLY, "java/lang/Byte"); + jclass cShort = ENVPTR->FindClass(ENVONLY, "java/lang/Short"); + jclass cInt = ENVPTR->FindClass(ENVONLY, "java/lang/Integer"); + jclass cLong = ENVPTR->FindClass(ENVONLY, "java/lang/Long"); + jclass cFloat = ENVPTR->FindClass(ENVONLY, "java/lang/Float"); + jclass cDouble = ENVPTR->FindClass(ENVONLY, "java/lang/Double"); + + jmethodID boolValueMid = ENVPTR->GetMethodID(ENVONLY, cBool, "booleanValue", "()Z"); + jmethodID byteValueMid = ENVPTR->GetMethodID(ENVONLY, cByte, "byteValue", "()B"); + jmethodID shortValueMid = ENVPTR->GetMethodID(ENVONLY, cShort, "shortValue", "()S"); + jmethodID intValueMid = ENVPTR->GetMethodID(ENVONLY, cInt, "intValue", "()I"); + jmethodID longValueMid = ENVPTR->GetMethodID(ENVONLY, cLong, "longValue", "()J"); + jmethodID floatValueMid = ENVPTR->GetMethodID(ENVONLY, cFloat, "floatValue", "()F"); + jmethodID doubleValueMid = ENVPTR->GetMethodID(ENVONLY, cDouble, "doubleValue", "()D"); + + /* Convert each list to a vlen element */ + for (i = 0; i < (size_t)n; i++) { + if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + // retrieve the java.util.List interface class + jclass cList = ENVPTR->FindClass(ENVONLY, "java/util/List"); + + // retrieve the toArray method and invoke it + jmethodID mToArray = ENVPTR->GetMethodID(ENVONLY, cList, "toArray", "()[Ljava/lang/Object;"); + if (mToArray == NULL) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, jList, mToArray); + jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array); + + cp_vp = (char *)rawBuf + i * typeSize; + ((hvl_t *)cp_vp)->len = jnelmts; + + if (NULL == (((hvl_t *)cp_vp)->p = HDmalloc(jnelmts * vlSize))) + H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DwriteVL: failed to allocate vlen ptr buffer"); + jobject jobj = NULL; + for (j = 0; j < (int)jnelmts; j++) { + if (NULL == (jobj = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)array, (jsize)j))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + switch (vlClass) { + /* case H5T_BOOL: { + jboolean boolValue = ENVPTR->CallBooleanMethod(ENVONLY, jobj, boolValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&boolValue)[x]; + } + break; + } */ + case H5T_INTEGER: { + switch (vlSize) { + case sizeof(jbyte): { + jbyte byteValue = ENVPTR->CallByteMethod(ENVONLY, jobj, byteValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&byteValue)[x]; + } + break; + } + case sizeof(jshort): { + jshort shortValue = ENVPTR->CallShortMethod(ENVONLY, jobj, shortValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&shortValue)[x]; + } + break; + } + case sizeof(jint): { + jint intValue = ENVPTR->CallIntMethod(ENVONLY, jobj, intValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&intValue)[x]; + } + break; + } + case sizeof(jlong): { + jlong longValue = ENVPTR->CallLongMethod(ENVONLY, jobj, longValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&longValue)[x]; + } + break; + } + } + break; + } + case H5T_FLOAT: { + switch (vlSize) { + case sizeof(jfloat): { + jfloat floatValue = ENVPTR->CallFloatMethod(ENVONLY, jobj, floatValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&floatValue)[x]; + } + break; + } + case sizeof(jdouble): { + jdouble doubleValue = ENVPTR->CallDoubleMethod(ENVONLY, jobj, doubleValueMid); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)&doubleValue)[x]; + } + break; + } + } + break; + } + case H5T_REFERENCE: { + jbyte *barray = (jbyte *)ENVPTR->GetByteArrayElements(ENVONLY, jobj, 0); + for (x = 0; x < (int)vlSize; x++) { + ((char *)((hvl_t *)cp_vp)->p)[j * vlSize + x] = ((char *)barray)[x]; + } + ENVPTR->ReleaseByteArrayElements(ENVONLY, jobj, barray, 0); + break; + } + default: + H5_UNIMPLEMENTED(ENVONLY, "H5DwriteVL: invalid class type"); + break; + } + ENVPTR->DeleteLocalRef(ENVONLY, jobj); + } + ENVPTR->DeleteLocalRef(ENVONLY, jList); + } /* end for (i = 0; i < n; i++) */ + + if ((status = H5Dwrite((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, rawBuf)) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (rawBuf) + HDfree(rawBuf); + } + else { + PIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, &writeBufIsCopy, "H5DwriteVL: write buffer not pinned"); + if ((status = H5Dwrite((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, + (hid_t)file_space_id, (hid_t)xfer_plist_id, writeBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Treclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + + if (type_class != H5T_VLEN) + UNPIN_BYTE_ARRAY(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); + } + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5DwriteVL */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Dread_VLStrings + * Signature: (JJJJJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Dread_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, + jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, + jobjectArray buf) +{ + H5T_class_t type_class; htri_t isStr = 0; htri_t isVlenStr = 0; htri_t isComplex = 0; @@ -1111,7 +1530,7 @@ Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DreadVL: read buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DreadVLStrings: read buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1163,7 +1582,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dread_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Dread_1VLStrings */ /* * Helper method to read in a buffer of variable-length strings from an HDF5 @@ -1315,54 +1734,15 @@ done: return status; } -/** - * Read VLEN data into array of arrays. - * Object[] buf contains VL arrays of data points - * Currently only deal with variable length of atomic data types - */ -/* old version */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Dread_VLStrings - * Signature: (JJJJJ[Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Dread_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, - jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, - jobjectArray buf) -{ - htri_t isVlenStr = 0; - herr_t status = FAIL; - - UNUSED(clss); - - if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dread_VLStrings: read buffer is NULL"); - - if ((isVlenStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (isVlenStr) { - if ((status = H5DreadVL_str(env, (hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, - (hid_t)file_space_id, (hid_t)xfer_plist_id, buf)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } - else - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_VLStrings: datatype is not variable length String"); - -done: - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dread_1VLStrings */ - /* * Class: hdf_hdf5lib_H5 - * Method: H5DwriteVL + * Method: H5Dwrite_VLStrings * Signature: (JJJJJ[Ljava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, - jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) +Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, + jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, + jobjectArray buf) { H5T_class_t type_class; htri_t isStr = 0; @@ -1375,7 +1755,7 @@ Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong UNUSED(clss); if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DwriteVL: write buffer is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5DwriteVLStrings: write buffer is NULL"); if ((isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1427,7 +1807,7 @@ done: H5Tclose(nested_tid); return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dwrite_1VL */ +} /* end Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings */ /* * Helper method to convert an array of Java strings into a buffer of C-strings. @@ -1440,7 +1820,7 @@ H5DwriteVL_str(JNIEnv *env, hid_t dataset_id, hid_t mem_type_id, hid_t mem_space const char *utf8 = NULL; jstring obj; jsize size; - jsize i; + jint i; char ** writeBuf = NULL; herr_t status = FAIL; @@ -1512,7 +1892,7 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si jobjectArray buf) { const char *utf8 = NULL; - jstring obj = NULL; + jstring jstr = NULL; hbool_t close_mem_space = FALSE; size_t typeSize; size_t i; @@ -1549,7 +1929,7 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AwriteVL_asstr: failed to allocate write buffer"); for (i = 0; i < (size_t)n; ++i) { - if (NULL == (obj = (jstring)ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) { + if (NULL == (jstr = (jstring)ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)buf, (jsize)i))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); /* @@ -1560,11 +1940,11 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si } /* - * length = ENVPTR->GetStringUTFLength(ENVONLY, obj); + * length = ENVPTR->GetStringUTFLength(ENVONLY, jstr); * CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); */ - PIN_JAVA_STRING(ENVONLY, obj, utf8, NULL, "H5DwriteVL_asstr: failed to pin string buffer"); + PIN_JAVA_STRING(ENVONLY, jstr, utf8, NULL, "H5DwriteVL_asstr: failed to pin string buffer"); /* * TODO: If the string isn't a copy, we should probably make @@ -1574,10 +1954,10 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si if (!h5str_convert(ENVONLY, (char **)&utf8, did, tid, &(((char *)writeBuf)[i * typeSize]), 0)) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - UNPIN_JAVA_STRING(ENVONLY, obj, utf8); + UNPIN_JAVA_STRING(ENVONLY, jstr, utf8); utf8 = NULL; - ENVPTR->DeleteLocalRef(ENVONLY, obj); + ENVPTR->DeleteLocalRef(ENVONLY, jstr); } /* end for (i = 0; i < size; ++i) */ if ((status = H5Dwrite(did, tid, mem_sid, file_sid, xfer_plist_id, writeBuf)) < 0) @@ -1585,7 +1965,7 @@ H5DwriteVL_asstr(JNIEnv *env, hid_t did, hid_t tid, hid_t mem_sid, hid_t file_si done: if (utf8) - UNPIN_JAVA_STRING(ENVONLY, obj, utf8); + UNPIN_JAVA_STRING(ENVONLY, jstr, utf8); if (writeBuf) { H5Treclaim(tid, mem_space, xfer_plist_id, writeBuf); HDfree(writeBuf); @@ -1598,39 +1978,6 @@ done: /* * Class: hdf_hdf5lib_H5 - * Method: H5Dwrite_VLStrings - * Signature: (JJJJJ[Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, - jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, - jobjectArray buf) -{ - htri_t isVlenStr = 0; - herr_t status = FAIL; - - UNUSED(clss); - - if (NULL == buf) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_VLStrings: write buffer is NULL"); - - if ((isVlenStr = H5Tis_variable_str((hid_t)mem_type_id)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - - if (isVlenStr) { - if ((status = H5DwriteVL_str(env, (hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, - (hid_t)file_space_id, (hid_t)xfer_plist_id, buf)) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } /* end if */ - else - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dwrite_VLStrings: datatype is not variable length String"); - -done: - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Dwrite_1VLStrings */ - -/* - * Class: hdf_hdf5lib_H5 * Method: H5Dread_reg_ref * Signature: (JJJJJ[Ljava/lang/String;)I */ diff --git a/java/src/jni/h5dImp.h b/java/src/jni/h5dImp.h index e339dad..f79cc2c 100644 --- a/java/src/jni/h5dImp.h +++ b/java/src/jni/h5dImp.h @@ -177,7 +177,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *, jclass, jl /* * Class: hdf_hdf5lib_H5 * Method: H5DreadVL - * Signature: (JJJJJ[Ljava/lang/String;)I + * Signature: (JJJJJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong, jobjectArray); @@ -185,7 +185,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *, jclass, jlong, jl /* * Class: hdf_hdf5lib_H5 * Method: H5DwriteVL - * Signature: (JJJJJ[Ljava/lang/String;)I + * Signature: (JJJJJ[Ljava/util/ArrayList;)I */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *, jclass, jlong, jlong, jlong, jlong, jlong, jobjectArray); diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 2de5d87..966bee5 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -52,6 +52,7 @@ void * edata; /* Local Prototypes */ /********************/ +int h5str_old_region_dataset(JNIEnv *env, h5str_t *out_str, hid_t container, void *ref_buf, int expand_data); int h5str_region_dataset(JNIEnv *env, h5str_t *out_str, H5R_ref_t *ref_vp, int expand_data); static int h5str_dump_region_blocks(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj, @@ -63,7 +64,6 @@ static int h5str_is_zero(const void *_mem, size_t size); static hid_t h5str_get_native_type(hid_t type); static hid_t h5str_get_little_endian_type(hid_t type); static hid_t h5str_get_big_endian_type(hid_t type); -static htri_t h5str_detect_vlen(hid_t tid); static htri_t h5str_detect_vlen_str(hid_t tid); static int h5str_dump_simple_data(JNIEnv *env, FILE *stream, hid_t container, hid_t type, void *_mem, hsize_t nelmts); @@ -642,6 +642,33 @@ done: } /* end h5str_convert */ /*------------------------------------------------------------------------- + * Function: h5str_sprint_old_reference + * + * Purpose: Object reference -- show the name of the 1.10 referenced object. + * + * Return: SUCCEED or FAIL + *------------------------------------------------------------------------- + */ +int +h5str_sprint_old_reference(JNIEnv *env, h5str_t *out_str, hid_t region_obj, void *ref_buf) +{ + hid_t region = H5I_INVALID_HID; + char ref_name[1024]; + + int ret_value = FAIL; + + if ((H5Rget_name(region_obj, H5R_DATASET_REGION, ref_buf, (char *)ref_name, 1024)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!h5str_append(out_str, ref_name)) + H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); + + ret_value = SUCCEED; +done: + + return ret_value; +} /* h5str_sprint_reference */ + +/*------------------------------------------------------------------------- * Function: h5str_sprint_reference * * Purpose: Object reference -- show the name of the referenced object. @@ -705,6 +732,48 @@ done: } /* h5str_sprint_reference */ int +h5str_old_region_dataset(JNIEnv *env, h5str_t *out_str, hid_t container, void *ref_buf, int expand_data) +{ + H5S_sel_type region_type = H5S_SEL_ERROR; + hid_t region_obj = H5I_INVALID_HID; + hid_t region_sid = H5I_INVALID_HID; + + int ret_value = FAIL; + + if ((region_obj = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, ref_buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((region_sid = H5Rget_region(container, H5R_DATASET_REGION, ref_buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (expand_data == 0) + if (h5str_sprint_old_reference(ENVONLY, out_str, region_obj, ref_buf) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if ((region_type = H5Sget_select_type(region_sid)) > H5S_SEL_ERROR) { + if (H5S_SEL_POINTS == region_type) { + if (h5str_dump_region_points(ENVONLY, out_str, region_sid, region_obj, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else if (H5S_SEL_HYPERSLABS == region_type) { + if (h5str_dump_region_blocks(ENVONLY, out_str, region_sid, region_obj, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + } + + ret_value = SUCCEED; +done: + if (region_sid >= 0) + if (H5Sclose(region_sid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (region_obj >= 0) + if (H5Dclose(region_obj) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + return ret_value; +} + +int h5str_region_dataset(JNIEnv *env, h5str_t *out_str, H5R_ref_t *ref_vp, int expand_data) { hid_t new_obj_id = H5I_INVALID_HID; @@ -1106,125 +1175,209 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i } case H5T_REFERENCE: { - /* H5T_STD_REF */ - hid_t new_obj_id = H5I_INVALID_HID; - H5O_type_t obj_type = -1; /* Object type */ - H5R_type_t ref_type; /* Reference type */ - - H5R_ref_t *ref_vp = (H5R_ref_t *)cptr; - - ref_type = H5Rget_type(ref_vp); - if (!h5str_is_zero(ref_vp, H5Tget_size(H5T_STD_REF))) { - switch (ref_type) { - case H5R_OBJECT1: - if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { - switch (obj_type) { - case H5O_TYPE_DATASET: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - break; - - case H5O_TYPE_GROUP: - case H5O_TYPE_NAMED_DATATYPE: - case H5O_TYPE_MAP: - case H5O_TYPE_UNKNOWN: - case H5O_TYPE_NTYPES: - default: { - /* Object references -- show the type and OID of the referenced object. */ - H5O_info2_t oi; - char * obj_tok_str = NULL; - if ((new_obj_id = H5Ropen_object(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= - 0) { - H5Oget_info3(new_obj_id, &oi, H5O_INFO_BASIC); - H5Otoken_to_str(new_obj_id, &oi.token, &obj_tok_str); - if (H5Dclose(new_obj_id) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } - else - H5_LIBRARY_ERROR(ENVONLY); - - size_t this_len = 14; - if (NULL == (this_str = (char *)HDmalloc(this_len))) - H5_OUT_OF_MEMORY_ERROR( - ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsnprintf(this_str, this_len, "%u-", (unsigned)oi.type) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); - if (!h5str_append(out_str, this_str)) - H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); - HDfree(this_str); - this_str = NULL; - - /* Print OID */ - { - char *token_str; - - H5Otoken_to_str(tid, &oi.token, &token_str); - - size_t that_len = 64 + strlen(token_str) + 1; - if (NULL == (this_str = HDmalloc(that_len))) - H5_OUT_OF_MEMORY_ERROR( - ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsnprintf(this_str, that_len, "%lu:%s", oi.fileno, token_str) < - 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); - - H5free_memory(token_str); - } - } break; - } /* end switch */ - } - else - H5_LIBRARY_ERROR(ENVONLY); - break; - case H5R_DATASET_REGION1: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - break; - case H5R_OBJECT2: - if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { - switch (obj_type) { - case H5O_TYPE_GROUP: - break; - - case H5O_TYPE_DATASET: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - break; - - case H5O_TYPE_NAMED_DATATYPE: - break; - - case H5O_TYPE_MAP: - case H5O_TYPE_UNKNOWN: - case H5O_TYPE_NTYPES: - default: - break; - } /* end switch */ - } - else - H5_ASSERTION_ERROR(ENVONLY, "h5str_sprintf: H5R_OBJECT2 failed"); + if (H5R_DSET_REG_REF_BUF_SIZE == typeSize) { + if (h5str_old_region_dataset(ENVONLY, out_str, container, cptr, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else if (H5R_OBJ_REF_BUF_SIZE == typeSize) { + H5O_info1_t oi; + hid_t obj = H5I_INVALID_HID; + + /* + * Object references -- show the type and OID of the referenced + * object. + */ + + if (NULL == (this_str = (char *)HDmalloc(64))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if ((obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, cptr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Oget_info2(obj, &oi, H5O_INFO_ALL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Print object data and close object */ + switch (oi.type) { + case H5O_TYPE_GROUP: + if (HDsprintf(this_str, "%s %llu", H5_TOOLS_GROUP, oi.addr) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; - case H5R_DATASET_REGION2: - if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + case H5O_TYPE_DATASET: + if (HDsprintf(this_str, "%s %llu", H5_TOOLS_DATASET, oi.addr) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; - case H5R_ATTR: - if ((new_obj_id = H5Ropen_attr(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= 0) { - if (h5str_dump_region_attribute(ENVONLY, out_str, new_obj_id) < 0) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - if (H5Aclose(new_obj_id) < 0) - H5_LIBRARY_ERROR(ENVONLY); - } + + case H5O_TYPE_NAMED_DATATYPE: + if (HDsprintf(this_str, "%s %llu", H5_TOOLS_DATATYPE, oi.addr) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; - case H5R_BADTYPE: - case H5R_MAXTYPE: + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: default: + if (HDsprintf(this_str, "%u-%llu", (unsigned)oi.type, oi.addr) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); break; } /* end switch */ + + if (H5Oclose(obj) < 0) + H5_LIBRARY_ERROR(ENVONLY); + obj = H5I_INVALID_HID; } + else { + /* H5T_STD_REF */ + hid_t new_obj_id = H5I_INVALID_HID; + H5O_type_t obj_type = -1; /* Object type */ + H5R_type_t ref_type; /* Reference type */ + + H5R_ref_t *ref_vp = (H5R_ref_t *)cptr; + + ref_type = H5Rget_type(ref_vp); + if (!h5str_is_zero(ref_vp, H5Tget_size(H5T_STD_REF))) { + switch (ref_type) { + case H5R_OBJECT1: + if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { + switch (obj_type) { + case H5O_TYPE_DATASET: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + + case H5O_TYPE_GROUP: + case H5O_TYPE_NAMED_DATATYPE: + case H5O_TYPE_MAP: + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: { + /* Object references -- show the type and + * OID of the referenced object. */ + H5O_info2_t oi; + char * obj_tok_str = NULL; + if ((new_obj_id = H5Ropen_object(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= + 0) { + H5Oget_info3(new_obj_id, &oi, H5O_INFO_BASIC); + H5Otoken_to_str(new_obj_id, &oi.token, &obj_tok_str); + if (H5Dclose(new_obj_id) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + else + H5_LIBRARY_ERROR(ENVONLY); - if (H5Rdestroy(ref_vp) < 0) - H5_LIBRARY_ERROR(ENVONLY); + size_t this_len = 14; + if (NULL == (this_str = (char *)HDmalloc(this_len))) + H5_OUT_OF_MEMORY_ERROR( + ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + switch (oi.type) { + case H5O_TYPE_GROUP: + if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_GROUP) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + + case H5O_TYPE_DATASET: + if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_DATASET) < + 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + + case H5O_TYPE_NAMED_DATATYPE: + if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_DATATYPE) < + 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + if (HDsnprintf(this_str, this_len, "%u-", (unsigned)oi.type) < + 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + break; + } /* end switch */ + if (!h5str_append(out_str, this_str)) + H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); + HDfree(this_str); + this_str = NULL; + + /* Print OID */ + { + char *token_str; + + H5Otoken_to_str(tid, &oi.token, &token_str); + + size_t that_len = 64 + strlen(token_str) + 1; + if (NULL == (this_str = HDmalloc(that_len))) + H5_OUT_OF_MEMORY_ERROR( + ENVONLY, + "h5str_sprintf: failed to allocate string buffer"); + if (HDsnprintf(this_str, that_len, "%lu:%s", oi.fileno, + token_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: HDsnprintf failure"); + + H5free_memory(token_str); + } + } break; + } /* end switch */ + } + else + H5_LIBRARY_ERROR(ENVONLY); + break; + case H5R_DATASET_REGION1: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + case H5R_OBJECT2: + if (H5Rget_obj_type3(ref_vp, H5P_DEFAULT, &obj_type) >= 0) { + switch (obj_type) { + case H5O_TYPE_GROUP: + break; + + case H5O_TYPE_DATASET: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + + case H5O_TYPE_NAMED_DATATYPE: + break; + + case H5O_TYPE_MAP: + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + break; + } /* end switch */ + } + else + H5_ASSERTION_ERROR(ENVONLY, "h5str_sprintf: H5R_OBJECT2 failed"); + break; + case H5R_DATASET_REGION2: + if (h5str_region_dataset(ENVONLY, out_str, ref_vp, expand_data) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + case H5R_ATTR: + if ((new_obj_id = H5Ropen_attr(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) >= 0) { + if (h5str_dump_region_attribute(ENVONLY, out_str, new_obj_id) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + if (H5Aclose(new_obj_id) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + break; + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + break; + } /* end switch */ + } + + if (H5Rdestroy(ref_vp) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } break; } @@ -1761,7 +1914,7 @@ h5str_is_zero(const void *_mem, size_t size) * Negative value: error occurred *------------------------------------------------------------------------- */ -static htri_t +htri_t h5str_detect_vlen(hid_t tid) { htri_t ret = FAIL; @@ -3118,29 +3271,65 @@ done: return ret_value; } +/*------------------------------------------------------------------------- + * Function: H5Tdetect_variable_str + * + * Purpose: Recursive check for variable length string of a datatype. + * + * Return: TRUE : type contains any variable length string + * FALSE : type doesn't contain any variable length string + * Negative value: failed + *------------------------------------------------------------------------- + */ htri_t H5Tdetect_variable_str(hid_t tid) { - htri_t ret_val = 0; - - if (H5Tget_class(tid) == H5T_COMPOUND) { - unsigned i; - unsigned nm = (unsigned)H5Tget_nmembers(tid); - for (i = 0; i < nm; i++) { - htri_t status = 0; - hid_t mtid = 0; - if ((mtid = H5Tget_member_type(tid, i)) < 0) - return FAIL; /* exit immediately on error */ - if ((status = H5Tdetect_variable_str(mtid)) < 0) - return status; /* exit immediately on error */ - ret_val |= status; + H5T_class_t tclass = -1; + htri_t ret = FALSE; + + ret = H5Tis_variable_str(tid); + if ((ret == TRUE) || (ret < 0)) + goto done; + + tclass = H5Tget_class(tid); + if (tclass == H5T_ARRAY || tclass == H5T_VLEN) { + hid_t btid = H5Tget_super(tid); + + if (btid < 0) { + ret = (htri_t)btid; + goto done; + } + ret = H5Tdetect_variable_str(btid); + if ((ret == TRUE) || (ret < 0)) { + H5Tclose(btid); + goto done; + } + } + else if (tclass == H5T_COMPOUND) { + unsigned nmembs; + int snmembs = H5Tget_nmembers(tid); + unsigned u; + + if (snmembs < 0) { + ret = FAIL; + goto done; + } + nmembs = (unsigned)snmembs; + + for (u = 0; u < nmembs; u++) { + hid_t mtid = H5Tget_member_type(tid, u); + + ret = H5Tdetect_variable_str(mtid); + if ((ret == TRUE) || (ret < 0)) { + H5Tclose(mtid); + goto done; + } H5Tclose(mtid); - } /* end for */ - } /* end if */ - else - ret_val = H5Tis_variable_str(tid); + } + } - return ret_val; +done: + return ret; } /* end H5Tdetect_variable_str */ static int diff --git a/java/src/jni/h5util.h b/java/src/jni/h5util.h index 6c568e1..3146c06 100644 --- a/java/src/jni/h5util.h +++ b/java/src/jni/h5util.h @@ -39,8 +39,10 @@ extern void h5str_new(h5str_t *str, size_t len); extern void h5str_free(h5str_t *str); extern void h5str_resize(h5str_t *str, size_t new_len); extern char * h5str_append(h5str_t *str, const char *cstr); +extern htri_t h5str_detect_vlen(hid_t tid); extern size_t h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_buf, size_t out_buf_offset); +extern int h5str_sprint_old_reference(JNIEnv *env, h5str_t *out_str, hid_t region_obj, void *ref_buf); extern int h5str_sprint_reference(JNIEnv *env, h5str_t *out_str, void *ref_p); extern size_t h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *in_buf, int expand_data); diff --git a/java/src/jni/nativeData.c b/java/src/jni/nativeData.c index 9e63f4f..ac9168b 100644 --- a/java/src/jni/nativeData.c +++ b/java/src/jni/nativeData.c @@ -46,8 +46,7 @@ extern "C" { /* returns int [] */ JNIEXPORT jintArray JNICALL -Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B(JNIEnv *env, jclass clss, - jbyteArray bdata) /* IN: array of bytes */ +Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B(JNIEnv *env, jclass clss, jbyteArray bdata) { jintArray rarray = NULL; jboolean bb; diff --git a/java/test/TestH5A.java b/java/test/TestH5A.java index fed13ce..96ce5b5 100644 --- a/java/test/TestH5A.java +++ b/java/test/TestH5A.java @@ -20,6 +20,8 @@ import static org.junit.Assert.fail; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; @@ -637,9 +639,8 @@ public class TestH5A { attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_INC, 0, lapl_id); assertNotNull(attr_info); - assertTrue("Corder ", - attr_info.corder == - 0); // should equal 0 as this is the order of 1st attribute created. + assertTrue("Corder ", attr_info.corder == + 0); // should equal 0 as this is the order of 1st attribute created. assertEquals(attr_info.data_size, H5.H5Aget_storage_size(attr_id)); // Verify info for 2nd attribute, in increasing creation order @@ -653,33 +654,29 @@ public class TestH5A { attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_DEC, 0, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 1); // should equal 1 as this is the order of 2nd attribute created. + assertTrue("Corder", attr_info.corder == + 1); // should equal 1 as this is the order of 2nd attribute created. // verify info for 1st attribute, in decreasing creation order attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_CRT_ORDER, HDF5Constants.H5_ITER_DEC, 1, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 0); // should equal 0 as this is the order of 1st attribute created. + assertTrue("Corder", attr_info.corder == + 0); // should equal 0 as this is the order of 1st attribute created. // verify info for 1st attribute, in increasing name order attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_INC, 1, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 0); // should equal 0 as this is the order of 1st attribute created. + assertTrue("Corder", attr_info.corder == + 0); // should equal 0 as this is the order of 1st attribute created. // verify info for 2nd attribute, in decreasing name order attr_info = H5.H5Aget_info_by_idx(H5did, ".", HDF5Constants.H5_INDEX_NAME, HDF5Constants.H5_ITER_DEC, 1, lapl_id); assertNotNull(attr_info); - assertTrue("Corder", - attr_info.corder == - 1); // should equal 1 as this is the order of 2nd attribute created. + assertTrue("Corder", attr_info.corder == + 1); // should equal 1 as this is the order of 2nd attribute created. } catch (Throwable err) { err.printStackTrace(); @@ -1075,7 +1072,7 @@ public class TestH5A { HDF5Constants.H5P_DEFAULT); assertTrue("testH5Awrite_readVL: ", attr_id >= 0); - H5.H5AwriteVL(attr_id, atype_id, str_data); + H5.H5Awrite_VLStrings(attr_id, atype_id, str_data); H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); @@ -1087,7 +1084,7 @@ public class TestH5A { strs[j] = ""; } try { - H5.H5AreadVL(attr_id, atype_id, strs); + H5.H5Aread_VLStrings(attr_id, atype_id, strs); } catch (Exception ex) { ex.printStackTrace(); @@ -1162,12 +1159,12 @@ public class TestH5A { fail("H5.H5Acreate: " + err); } - /* Close the property list, and get the attribute's property list */ + // Close the property list, and get the attribute's property list H5.H5Pclose(plist_id); plist_id = H5.H5Aget_create_plist(attribute_id); assertTrue(plist_id > 0); - /* Get the character encoding and ensure that it is the default (ASCII) */ + // Get the character encoding and ensure that it is the default (ASCII) try { char_encoding = H5.H5Pget_char_encoding(plist_id); } @@ -1371,4 +1368,212 @@ public class TestH5A { } } } + + @Test + public void testH5AVLwr() + { + String attr_int_name = "VLIntdata"; + String attr_dbl_name = "VLDbldata"; + long attr_int_id = HDF5Constants.H5I_INVALID_HID; + long attr_dbl_id = HDF5Constants.H5I_INVALID_HID; + long atype_int_id = HDF5Constants.H5I_INVALID_HID; + long atype_dbl_id = HDF5Constants.H5I_INVALID_HID; + long aspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + + ArrayList[] vl_int_data = new ArrayList[4]; + ArrayList[] vl_dbl_data = new ArrayList[4]; + try { + // Write Integer data + vl_int_data[0] = new ArrayList(Arrays.asList(1)); + vl_int_data[1] = new ArrayList(Arrays.asList(2, 3)); + vl_int_data[2] = new ArrayList(Arrays.asList(4, 5, 6)); + vl_int_data[3] = new ArrayList(Arrays.asList(7, 8, 9, 10)); + Class dataClass = vl_int_data.getClass(); + assertTrue("testH5AVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_int_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_U32LE); + assertTrue("testH5AVLwr.H5Tvlen_create: ", atype_int_id >= 0); + } + catch (Exception err) { + if (atype_int_id > 0) + try { + H5.H5Tclose(atype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_int_id = H5.H5Acreate(H5did, attr_int_name, atype_int_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5AVLwr: ", attr_int_id >= 0); + + H5.H5AwriteVL(attr_int_id, atype_int_id, vl_int_data); + } + catch (Exception err) { + if (attr_int_id > 0) + try { + H5.H5Aclose(attr_int_id); + } + catch (Exception ex) { + } + if (atype_int_id > 0) + try { + H5.H5Tclose(atype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + // Write Double data + vl_dbl_data[0] = new ArrayList(Arrays.asList(1.1)); + vl_dbl_data[1] = new ArrayList(Arrays.asList(2.2, 3.3)); + vl_dbl_data[2] = new ArrayList(Arrays.asList(4.4, 5.5, 6.6)); + vl_dbl_data[3] = new ArrayList(Arrays.asList(7.7, 8.8, 9.9, 10.0)); + dataClass = vl_dbl_data.getClass(); + assertTrue("testH5AVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_dbl_id = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_DOUBLE); + assertTrue("testH5AVLwr.H5Tvlen_create: ", atype_dbl_id >= 0); + } + catch (Exception err) { + if (atype_dbl_id > 0) + try { + H5.H5Tclose(atype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_dbl_id = H5.H5Acreate(H5did, attr_dbl_name, atype_dbl_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5AVLwr: ", attr_dbl_id >= 0); + + H5.H5AwriteVL(attr_dbl_id, atype_dbl_id, vl_dbl_data); + } + catch (Exception err) { + if (attr_dbl_id > 0) + try { + H5.H5Aclose(attr_dbl_id); + } + catch (Exception ex) { + } + if (atype_dbl_id > 0) + try { + H5.H5Tclose(atype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Integer data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_int_id, atype_int_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5AVLwr:" + vl_readbuf[0].get(0), + vl_int_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[1].get(0), + vl_int_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[2].get(0), + vl_int_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[3].get(0), + vl_int_data[3].get(0).equals(vl_readbuf[3].get(0))); + + // Read Double data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_dbl_id, atype_dbl_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5AVLwr:" + vl_readbuf[0].get(0), + vl_dbl_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[1].get(0), + vl_dbl_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[2].get(0), + vl_dbl_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5AVLwr:" + vl_readbuf[3].get(0), + vl_dbl_data[3].get(0).equals(vl_readbuf[3].get(0))); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5AVLwr: " + err); + } + finally { + if (attr_dbl_id > 0) + try { + H5.H5Aclose(attr_dbl_id); + } + catch (Exception ex) { + } + if (attr_int_id > 0) + try { + H5.H5Aclose(attr_int_id); + } + catch (Exception ex) { + } + if (atype_dbl_id > 0) + try { + H5.H5Tclose(atype_dbl_id); + } + catch (Exception ex) { + } + if (atype_int_id > 0) + try { + H5.H5Tclose(atype_int_id); + } + catch (Exception ex) { + } + } + } } diff --git a/java/test/TestH5D.java b/java/test/TestH5D.java index 4bab1a9..f7e5702 100644 --- a/java/test/TestH5D.java +++ b/java/test/TestH5D.java @@ -17,6 +17,9 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; @@ -961,8 +964,8 @@ public class TestH5D { assertTrue("H5Dvlen_get_buf_size " + vl_size + " == " + str_data_bytes, vl_size == str_data_bytes); } - @Test(expected = IllegalArgumentException.class) - public void testH5Dvlen_read_invalid_buffer() throws Throwable + @Test + public void testH5Dvlen_read_default_buffer() throws Throwable { String[] str_data = {"Parting", "is such", "sweet", "sorrow.", "Testing", "one", "two", "three.", "Dog,", "man's", "best", "friend.", "Diamonds", "are", "a", "girls!", @@ -1013,4 +1016,218 @@ public class TestH5D { assertTrue("testH5Dvlen_write_read " + str_wdata[v] + " == " + str_rdata[v], str_wdata[v] == str_wdata[v]); } + + @Test + public void testH5DVLwr() + { + String dset_int_name = "VLIntdata"; + String dset_dbl_name = "VLDbldata"; + long dset_int_id = HDF5Constants.H5I_INVALID_HID; + long dset_dbl_id = HDF5Constants.H5I_INVALID_HID; + long dtype_int_id = HDF5Constants.H5I_INVALID_HID; + long dtype_dbl_id = HDF5Constants.H5I_INVALID_HID; + long dspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + + ArrayList[] vl_int_data = new ArrayList[4]; + ArrayList[] vl_dbl_data = new ArrayList[4]; + try { + // Write Integer data + vl_int_data[0] = new ArrayList(Arrays.asList(1)); + vl_int_data[1] = new ArrayList(Arrays.asList(2, 3)); + vl_int_data[2] = new ArrayList(Arrays.asList(4, 5, 6)); + vl_int_data[3] = new ArrayList(Arrays.asList(7, 8, 9, 10)); + Class dataClass = vl_int_data.getClass(); + assertTrue("testH5DVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_int_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_U32LE); + assertTrue("testH5DVLwr.H5Tvlen_create: ", dtype_int_id >= 0); + } + catch (Exception err) { + if (dtype_int_id > 0) + try { + H5.H5Tclose(dtype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_int_id = + H5.H5Dcreate(H5fid, dset_int_name, dtype_int_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5DVLwr: ", dset_int_id >= 0); + + H5.H5DwriteVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_int_data); + } + catch (Exception err) { + if (dset_int_id > 0) + try { + H5.H5Dclose(dset_int_id); + } + catch (Exception ex) { + } + if (dtype_int_id > 0) + try { + H5.H5Tclose(dtype_int_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + // Write Double data + vl_dbl_data[0] = new ArrayList(Arrays.asList(1.1)); + vl_dbl_data[1] = new ArrayList(Arrays.asList(2.2, 3.3)); + vl_dbl_data[2] = new ArrayList(Arrays.asList(4.4, 5.5, 6.6)); + vl_dbl_data[3] = new ArrayList(Arrays.asList(7.7, 8.8, 9.9, 10.0)); + dataClass = vl_dbl_data.getClass(); + assertTrue("testH5DVLwr.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_dbl_id = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_DOUBLE); + assertTrue("testH5DVLwr.H5Tvlen_create: ", dtype_dbl_id >= 0); + } + catch (Exception err) { + if (dtype_dbl_id > 0) + try { + H5.H5Tclose(dtype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_dbl_id = + H5.H5Dcreate(H5fid, dset_dbl_name, dtype_dbl_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5DVLwr: ", dset_dbl_id >= 0); + + H5.H5DwriteVL(dset_dbl_id, dtype_dbl_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_dbl_data); + } + catch (Exception err) { + if (dset_dbl_id > 0) + try { + H5.H5Dclose(dset_dbl_id); + } + catch (Exception ex) { + } + if (dtype_dbl_id > 0) + try { + H5.H5Tclose(dtype_dbl_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Integer data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5DVLwr:" + vl_readbuf[0].get(0), + vl_int_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[1].get(0), + vl_int_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[2].get(0), + vl_int_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[3].get(0), + vl_int_data[3].get(0).equals(vl_readbuf[3].get(0))); + + // Read Double data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_dbl_id, dtype_dbl_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5DVLwr:" + vl_readbuf[0].get(0), + vl_dbl_data[0].get(0).equals(vl_readbuf[0].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[1].get(0), + vl_dbl_data[1].get(0).equals(vl_readbuf[1].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[2].get(0), + vl_dbl_data[2].get(0).equals(vl_readbuf[2].get(0))); + assertTrue("testH5DVLwr:" + vl_readbuf[3].get(0), + vl_dbl_data[3].get(0).equals(vl_readbuf[3].get(0))); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5DVLwr: " + err); + } + finally { + if (dset_dbl_id > 0) + try { + H5.H5Dclose(dset_dbl_id); + } + catch (Exception ex) { + } + if (dset_int_id > 0) + try { + H5.H5Dclose(dset_int_id); + } + catch (Exception ex) { + } + if (dtype_dbl_id > 0) + try { + H5.H5Tclose(dtype_dbl_id); + } + catch (Exception ex) { + } + if (dtype_int_id > 0) + try { + H5.H5Tclose(dtype_int_id); + } + catch (Exception ex) { + } + } + } } diff --git a/java/test/TestH5R.java b/java/test/TestH5R.java index 4e610bc..dd8634b 100644 --- a/java/test/TestH5R.java +++ b/java/test/TestH5R.java @@ -19,6 +19,9 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import hdf.hdf5lib.H5; import hdf.hdf5lib.HDF5Constants; @@ -528,4 +531,470 @@ public class TestH5R { byte[] ref = null; H5.H5Rget_attr_name(ref); } + + @Test + public void testH5RVLattr_ref() + { + String attr_obj_name = "VLObjRefdata"; + String attr_reg_name = "VLRegRefdata"; + long attr_obj_id = HDF5Constants.H5I_INVALID_HID; + long attr_reg_id = HDF5Constants.H5I_INVALID_HID; + long atype_obj_id = HDF5Constants.H5I_INVALID_HID; + long atype_reg_id = HDF5Constants.H5I_INVALID_HID; + long aspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + byte[] ref1 = null; + byte[] ref2 = null; + byte[] ref3 = null; + byte[] ref4 = null; + + try { + // Create reference on dataset + ref1 = H5.H5Rcreate(H5fid, "/dset", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref1); + ref2 = H5.H5Rcreate(H5gid, "dset2", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref2); + ref3 = H5.H5Rcreate(H5gid, "/dset", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + + // Create reference on group + ref4 = H5.H5Rcreate(H5gid, "/Group1", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5RVLattr_ref: " + err); + } + + ArrayList[] vl_obj_data = new ArrayList[4]; + ArrayList[] vl_reg_data = new ArrayList[4]; + try { + // Write Object Reference data + vl_obj_data[0] = new ArrayList(Arrays.asList(ref3)); + vl_obj_data[1] = new ArrayList(Arrays.asList(ref3, ref4)); + vl_obj_data[2] = new ArrayList(Arrays.asList(ref3, ref3, ref3)); + vl_obj_data[3] = new ArrayList(Arrays.asList(ref4, ref4, ref4, ref4)); + Class dataClass = vl_obj_data.getClass(); + assertTrue("testH5RVLattr_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_obj_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_OBJ); + assertTrue("testH5RVLattr_ref.H5Tvlen_create: ", atype_obj_id >= 0); + } + catch (Exception err) { + if (atype_obj_id > 0) + try { + H5.H5Tclose(atype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_obj_id = H5.H5Acreate(H5did, attr_obj_name, atype_obj_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLattr_ref: ", attr_obj_id >= 0); + + H5.H5AwriteVL(attr_obj_id, atype_obj_id, vl_obj_data); + } + catch (Exception err) { + if (attr_obj_id > 0) + try { + H5.H5Aclose(attr_obj_id); + } + catch (Exception ex) { + } + if (atype_obj_id > 0) + try { + H5.H5Tclose(atype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + // Write Region Reference data + vl_reg_data[0] = new ArrayList(Arrays.asList(ref1)); + vl_reg_data[1] = new ArrayList(Arrays.asList(ref1, ref2)); + vl_reg_data[2] = new ArrayList(Arrays.asList(ref1, ref1, ref1)); + vl_reg_data[3] = new ArrayList(Arrays.asList(ref2, ref2, ref2, ref2)); + dataClass = vl_reg_data.getClass(); + assertTrue("testH5RVLattr_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + atype_reg_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_DSETREG); + assertTrue("testH5RVLattr_ref.H5Tvlen_create: ", atype_reg_id >= 0); + } + catch (Exception err) { + if (atype_reg_id > 0) + try { + H5.H5Tclose(atype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + + try { + aspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(aspace_id > 0); + attr_reg_id = H5.H5Acreate(H5did, attr_reg_name, atype_reg_id, aspace_id, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLattr_ref: ", attr_reg_id >= 0); + + H5.H5AwriteVL(attr_reg_id, atype_reg_id, vl_reg_data); + } + catch (Exception err) { + if (attr_reg_id > 0) + try { + H5.H5Aclose(attr_reg_id); + } + catch (Exception ex) { + } + if (atype_reg_id > 0) + try { + H5.H5Tclose(atype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + finally { + if (aspace_id > 0) + try { + H5.H5Sclose(aspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Object Reference data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_obj_id, atype_obj_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_obj_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_obj_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_obj_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_obj_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + + // Read Region Reference data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5AreadVL(attr_reg_id, atype_reg_id, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_reg_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_reg_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_reg_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLattr_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_reg_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5RVLattr_ref: " + err); + } + finally { + if (attr_reg_id > 0) + try { + H5.H5Aclose(attr_reg_id); + } + catch (Exception ex) { + } + if (attr_obj_id > 0) + try { + H5.H5Aclose(attr_obj_id); + } + catch (Exception ex) { + } + if (atype_reg_id > 0) + try { + H5.H5Tclose(atype_reg_id); + } + catch (Exception ex) { + } + if (atype_obj_id > 0) + try { + H5.H5Tclose(atype_obj_id); + } + catch (Exception ex) { + } + } + } + + @Test + public void testH5RVLdset_ref() + { + String dset_obj_name = "VLObjRefdata"; + String dset_reg_name = "VLRegRefdata"; + long dset_obj_id = HDF5Constants.H5I_INVALID_HID; + long dset_reg_id = HDF5Constants.H5I_INVALID_HID; + long dtype_obj_id = HDF5Constants.H5I_INVALID_HID; + long dtype_reg_id = HDF5Constants.H5I_INVALID_HID; + long dspace_id = HDF5Constants.H5I_INVALID_HID; + long[] dims = {4}; + long lsize = 1; + byte[] ref1 = null; + byte[] ref2 = null; + byte[] ref3 = null; + byte[] ref4 = null; + + try { + // Create reference on dataset + ref1 = H5.H5Rcreate(H5fid, "/dset", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref1); + ref2 = H5.H5Rcreate(H5gid, "dset2", HDF5Constants.H5R_DATASET_REGION, H5dsid); + assertNotNull(ref2); + ref3 = H5.H5Rcreate(H5gid, "/dset", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + + // Create reference on group + ref4 = H5.H5Rcreate(H5gid, "/Group1", HDF5Constants.H5R_OBJECT, -1); + assertNotNull(ref3); + } + catch (Throwable err) { + err.printStackTrace(); + fail("testH5RVLattr_ref: " + err); + } + + ArrayList[] vl_obj_data = new ArrayList[4]; + ArrayList[] vl_reg_data = new ArrayList[4]; + try { + // Write Object Reference data + vl_obj_data[0] = new ArrayList(Arrays.asList(ref3)); + vl_obj_data[1] = new ArrayList(Arrays.asList(ref3, ref4)); + vl_obj_data[2] = new ArrayList(Arrays.asList(ref3, ref3, ref3)); + vl_obj_data[3] = new ArrayList(Arrays.asList(ref4, ref4, ref4, ref4)); + Class dataClass = vl_obj_data.getClass(); + assertTrue("testH5RVLdset_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_obj_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_OBJ); + assertTrue("testH5RVLdset_ref.H5Tvlen_create: ", dtype_obj_id >= 0); + } + catch (Exception err) { + if (dtype_obj_id > 0) + try { + H5.H5Tclose(dtype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_obj_id = + H5.H5Dcreate(H5fid, dset_obj_name, dtype_obj_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLdset_ref: ", dset_obj_id >= 0); + + H5.H5DwriteVL(dset_obj_id, dtype_obj_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_obj_data); + } + catch (Exception err) { + if (dset_obj_id > 0) + try { + H5.H5Dclose(dset_obj_id); + } + catch (Exception ex) { + } + if (dtype_obj_id > 0) + try { + H5.H5Tclose(dtype_obj_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + // Write Region Reference data + vl_reg_data[0] = new ArrayList(Arrays.asList(ref1)); + vl_reg_data[1] = new ArrayList(Arrays.asList(ref1, ref2)); + vl_reg_data[2] = new ArrayList(Arrays.asList(ref1, ref1, ref1)); + vl_reg_data[3] = new ArrayList(Arrays.asList(ref2, ref2, ref2, ref2)); + dataClass = vl_reg_data.getClass(); + assertTrue("testH5RVLdset_ref.getClass: " + dataClass, dataClass.isArray()); + + try { + dtype_reg_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_REF_DSETREG); + assertTrue("testH5RVLdset_ref.H5Tvlen_create: ", dtype_reg_id >= 0); + } + catch (Exception err) { + if (dtype_reg_id > 0) + try { + H5.H5Tclose(dtype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + + try { + dspace_id = H5.H5Screate_simple(1, dims, null); + assertTrue(dspace_id > 0); + dset_reg_id = + H5.H5Dcreate(H5fid, dset_reg_name, dtype_reg_id, dspace_id, HDF5Constants.H5P_DEFAULT, + HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT); + assertTrue("testH5RVLdset_ref: ", dset_reg_id >= 0); + + H5.H5DwriteVL(dset_reg_id, dtype_reg_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_reg_data); + } + catch (Exception err) { + if (dset_reg_id > 0) + try { + H5.H5Dclose(dset_reg_id); + } + catch (Exception ex) { + } + if (dtype_reg_id > 0) + try { + H5.H5Tclose(dtype_reg_id); + } + catch (Exception ex) { + } + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + finally { + if (dspace_id > 0) + try { + H5.H5Sclose(dspace_id); + } + catch (Exception ex) { + } + } + + H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL); + + for (int j = 0; j < dims.length; j++) { + lsize *= dims[j]; + } + + // Read Object Reference data + ArrayList[] vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_obj_id, dtype_obj_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_obj_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_obj_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_obj_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_obj_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + + // Read Region Reference data + vl_readbuf = new ArrayList[4]; + for (int j = 0; j < lsize; j++) + vl_readbuf[j] = new ArrayList(); + + try { + H5.H5DreadVL(dset_reg_id, dtype_reg_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL, + HDF5Constants.H5P_DEFAULT, vl_readbuf); + } + catch (Exception ex) { + ex.printStackTrace(); + } + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[0].get(0))[0], + ((byte[])vl_reg_data[0].get(0))[0] == ((byte[])vl_readbuf[0].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[1].get(0))[0], + ((byte[])vl_reg_data[1].get(0))[0] == ((byte[])vl_readbuf[1].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[2].get(0))[0], + ((byte[])vl_reg_data[2].get(0))[0] == ((byte[])vl_readbuf[2].get(0))[0]); + assertTrue("testH5RVLdset_ref:" + ((byte[])vl_readbuf[3].get(0))[0], + ((byte[])vl_reg_data[3].get(0))[0] == ((byte[])vl_readbuf[3].get(0))[0]); + } + catch (Throwable err) { + err.printStackTrace(); + fail("H5.testH5RVLdset_ref: " + err); + } + finally { + if (dset_reg_id > 0) + try { + H5.H5Dclose(dset_reg_id); + } + catch (Exception ex) { + } + if (dset_obj_id > 0) + try { + H5.H5Dclose(dset_obj_id); + } + catch (Exception ex) { + } + if (dtype_reg_id > 0) + try { + H5.H5Tclose(dtype_reg_id); + } + catch (Exception ex) { + } + if (dtype_obj_id > 0) + try { + H5.H5Tclose(dtype_obj_id); + } + catch (Exception ex) { + } + } + } } diff --git a/java/test/testfiles/JUnit-TestH5A.txt b/java/test/testfiles/JUnit-TestH5A.txt index 2026d21..efdd4a2 100644 --- a/java/test/testfiles/JUnit-TestH5A.txt +++ b/java/test/testfiles/JUnit-TestH5A.txt @@ -6,6 +6,7 @@ JUnit version 4.11 .testH5Aiterate .testH5Aopen_by_idx .testH5Aopen_invalidname +.testH5AVLwr .testH5Aopen .testH5Aget_info_by_name .testH5Aget_create_plist @@ -30,5 +31,5 @@ JUnit version 4.11 Time: XXXX -OK (28 tests) +OK (29 tests) diff --git a/java/test/testfiles/JUnit-TestH5D.txt b/java/test/testfiles/JUnit-TestH5D.txt index 987655b..288e6d0 100644 --- a/java/test/testfiles/JUnit-TestH5D.txt +++ b/java/test/testfiles/JUnit-TestH5D.txt @@ -4,6 +4,7 @@ JUnit version 4.11 .testH5Dcreate .testH5Dget_offset .testH5Dget_type +.testH5DVLwr .testH5Dfill .testH5Dopen .testH5Dcreate_anon @@ -11,15 +12,15 @@ JUnit version 4.11 .testH5Dget_storage_size_empty .testH5Diterate .testH5Dget_access_plist -.testH5Dvlen_read_invalid_buffer .testH5Dvlen_get_buf_size .testH5Dget_space_closed .testH5Dget_space_status .testH5Dvlen_write_read .testH5Dget_space .testH5Dget_type_closed +.testH5Dvlen_read_default_buffer Time: XXXX -OK (19 tests) +OK (20 tests) diff --git a/java/test/testfiles/JUnit-TestH5R.txt b/java/test/testfiles/JUnit-TestH5R.txt index a96fbb4..2420d62 100644 --- a/java/test/testfiles/JUnit-TestH5R.txt +++ b/java/test/testfiles/JUnit-TestH5R.txt @@ -4,6 +4,8 @@ JUnit version 4.11 .testH5Ropen_region_Nullref .testH5Requal_Nullref1 .testH5Requal_Nullref2 +.testH5RVLdset_ref +.testH5RVLattr_ref .testH5Rget_object .testH5Rget_obj_type3_Nullref .testH5Ropen_object_Nullref @@ -24,5 +26,5 @@ JUnit version 4.11 Time: XXXX -OK (22 tests) +OK (24 tests) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 8fe0df8..0901366 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -72,12 +72,48 @@ New Features Java Library: ------------- - - + - Added reference support to H5A and H5D read write vlen JNI functions. + + Added the implementation to handle VL references as an Array of Lists + of byte arrays. + + The JNI wrappers translate the Array of Lists to/from the hvl_t vlen + structures. The wrappers use the specified datatype arguments for the + List type translation, it is expected that the Java type is correct. + + (ADB - 2022/07/11, HDFFV-11318) + + - H5A and H5D read write vlen JNI functions were incorrect. + + Corrected the vlen function implementations for the basic primitive types. + The VLStrings functions now correctly use the implementation that had been + the VL functions. (VLStrings functions did not have an implementation.) + The new VL functions implementation now expect an Array of Lists between + Java and the JNI wrapper. + + The JNI wrappers translate the Array of Lists to/from the hvl_t vlen + structures. The wrappers use the specified datatype arguments for the + List type translation, it is expected that the Java type is correct. + + (ADB - 2022/07/07, HDFFV-11310) + + - H5A and H5D read write JNI functions had flawed vlen datatype check. + + Adapted tools function for JNI utils file. This reduced multiple calls + to a single check and variable. The variable can then be used to call + the H5Treclaim function. Adjusted existing test and added new test. + + (ADB - 2022/06/22) Tools: ------ - - + - 1.10 References in containers were not displayed properly by h5dump. + + Ported 1.10 tools display function to provide ability to inspect and + display 1.10 reference data. + + (ADB - 2022/06/22) High-Level APIs: diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 4e8dcc1..22d6677 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -1052,7 +1052,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai H5TOOLS_DEBUG("H5T_ENUM"); if (H5Tenum_nameof(type, vp, enum_name, sizeof enum_name) >= 0) - h5tools_str_append(str, h5tools_escape(enum_name, sizeof(enum_name))); + h5tools_str_append(str, "%s", h5tools_escape(enum_name, sizeof(enum_name))); else { size_t i; if (1 == nsize) @@ -1181,10 +1181,49 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai else if (H5Tequal(type, H5T_STD_REF_DSETREG)) { /* if(nsize == H5R_DSET_REG_REF_BUF_SIZE) */ H5TOOLS_DEBUG("H5T_REFERENCE:H5T_STD_REF_DSETREG"); + h5tools_str_append(str, H5_TOOLS_DATASET); + h5tools_str_sprint_old_reference(str, container, vp); } else if (H5Tequal(type, H5T_STD_REF_OBJ)) { /* if (nsize == H5R_OBJ_REF_BUF_SIZE) */ + /* + * Object references -- show the type and OID of the referenced object. + */ + H5O_info1_t oi; + H5TOOLS_DEBUG("H5T_REFERENCE:H5T_STD_REF_OBJ"); + obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, vp); + H5Oget_info2(obj, &oi, H5O_INFO_BASIC); + + /* Print object type and close object */ + switch (oi.type) { + case H5O_TYPE_GROUP: + h5tools_str_append(str, H5_TOOLS_GROUP); + break; + + case H5O_TYPE_DATASET: + h5tools_str_append(str, H5_TOOLS_DATASET); + break; + + case H5O_TYPE_NAMED_DATATYPE: + h5tools_str_append(str, H5_TOOLS_DATATYPE); + break; + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + h5tools_str_append(str, "%u-", (unsigned)oi.type); + break; + } /* end switch */ + H5Oclose(obj); + + /* Print OID */ + if (info->obj_hidefileno) + h5tools_str_append(str, info->obj_format, oi.addr); + else + h5tools_str_append(str, info->obj_format, oi.fileno, oi.addr); + + h5tools_str_sprint_old_reference(str, container, vp); } /* end else if (H5Tequal(type, H5T_STD_REF_OBJ)) */ } break; @@ -1265,6 +1304,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai nelmts = ((hvl_t *)((void *)cp_vp))->len; for (i = 0; i < nelmts; i++) { + H5TOOLS_DEBUG("H5T_VLEN %d of %ld", i, nelmts); if (i) h5tools_str_append(str, "%s", OPT(info->vlen_sep, "," OPTIONAL_LINE_BREAK)); @@ -1326,6 +1366,48 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai } /*------------------------------------------------------------------------- + * Function: h5tools_str_sprint_old_reference + * + * Purpose: Object reference -- show the name of the old referenced object. + * + * Return: Nothing + *------------------------------------------------------------------------- + */ +void +h5tools_str_sprint_old_reference(h5tools_str_t *str, hid_t container, void *vp) +{ + hid_t obj = H5I_INVALID_HID; + hid_t region = H5I_INVALID_HID; + char ref_name[1024]; + + H5TOOLS_START_DEBUG(" "); + + h5tools_str_append(str, " \""); + obj = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, vp); + if (obj >= 0) { + region = H5Rget_region(container, H5R_DATASET_REGION, vp); + if (region >= 0) { + H5Rget_name(obj, H5R_DATASET_REGION, vp, (char *)ref_name, 1024); + h5tools_str_append(str, "%s", ref_name); + + H5Sclose(region); + } /* end if (region >= 0) */ + H5Dclose(obj); + } /* end if (obj >= 0) */ + else { + obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, vp); + if (obj >= 0) { + H5Rget_name(obj, H5R_OBJECT, vp, (char *)ref_name, 1024); + h5tools_str_append(str, "%s", ref_name); + H5Dclose(obj); + } + } + h5tools_str_append(str, "\""); + + H5TOOLS_ENDDEBUG(" "); +} + +/*------------------------------------------------------------------------- * Function: h5tools_str_sprint_reference * * Purpose: Object reference -- show the name of the referenced object. @@ -1402,10 +1484,10 @@ h5tools_str_sprint_reference(h5tools_str_t *str, H5R_ref_t *ref_vp) static char * h5tools_escape(char *s /*in,out*/, size_t size) { - register size_t i; - const char * escape; - char octal[8]; - size_t n = HDstrlen(s); + size_t i; + const char *escape; + char octal[8]; + size_t n = HDstrlen(s); for (i = 0; i < n; i++) { switch (s[i]) { diff --git a/tools/lib/h5tools_str.h b/tools/lib/h5tools_str.h index eee87c9..15834bb 100644 --- a/tools/lib/h5tools_str.h +++ b/tools/lib/h5tools_str.h @@ -41,6 +41,7 @@ H5TOOLS_DLL void h5tools_str_dump_space_slabs(h5tools_str_t *, hid_t, const h5t h5tools_context_t *ctx); H5TOOLS_DLL void h5tools_str_dump_space_blocks(h5tools_str_t *, hid_t, const h5tool_format_t *); H5TOOLS_DLL void h5tools_str_dump_space_points(h5tools_str_t *, hid_t, const h5tool_format_t *); +H5TOOLS_DLL void h5tools_str_sprint_old_reference(h5tools_str_t *str, hid_t container, void *vp); H5TOOLS_DLL void h5tools_str_sprint_reference(h5tools_str_t *str, H5R_ref_t *vp); H5TOOLS_DLL 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); -- cgit v0.12