diff options
Diffstat (limited to 'java/src/jni')
-rw-r--r-- | java/src/jni/h5aImp.c | 818 | ||||
-rw-r--r-- | java/src/jni/h5aImp.h | 18 | ||||
-rw-r--r-- | java/src/jni/h5dImp.c | 805 | ||||
-rw-r--r-- | java/src/jni/h5dImp.h | 4 | ||||
-rw-r--r-- | java/src/jni/h5util.c | 243 | ||||
-rw-r--r-- | java/src/jni/h5util.h | 1 |
6 files changed, 1425 insertions, 464 deletions
diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index f06075c..065022d 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) { + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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) { + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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) { + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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) { + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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) { + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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) { + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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) { + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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 24263a5..136d82f 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) + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -371,7 +369,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); @@ -379,19 +377,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"); @@ -406,6 +400,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1short(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -429,7 +426,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); @@ -437,19 +434,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"); @@ -464,6 +457,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1short(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -486,28 +482,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"); @@ -522,6 +514,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1int(JNIEnv *env, jclass clss, jlong dataset_id, jlo done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -544,28 +539,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"); @@ -580,6 +571,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1int(JNIEnv *env, jclass clss, jlong dataset_id, jl done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -602,28 +596,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"); @@ -638,6 +628,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1long(JNIEnv *env, jclass clss, jlong dataset_id, jl done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -660,28 +653,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"); @@ -696,6 +685,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1long(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -718,28 +710,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"); @@ -754,6 +742,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1float(JNIEnv *env, jclass clss, jlong dataset_id, j done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -776,27 +767,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) - 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) + 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"); + /* 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, @@ -812,6 +799,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1float(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -835,7 +825,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); @@ -843,19 +833,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"); @@ -870,6 +856,9 @@ Java_hdf_hdf5lib_H5_H5Dread_1double(JNIEnv *env, jclass clss, jlong dataset_id, done: if (readBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, readBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, readBuf, (status < 0) ? JNI_ABORT : 0); } @@ -893,7 +882,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); @@ -901,19 +890,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"); @@ -928,6 +912,9 @@ Java_hdf_hdf5lib_H5_H5Dwrite_1double(JNIEnv *env, jclass clss, jlong dataset_id, done: if (writeBuf) { + if ((status >= 0) && vl_data_class) + H5Dvlen_reclaim(dataset_id, mem_space_id, H5P_DEFAULT, writeBuf); + if (isCriticalPinning) { UNPIN_ARRAY_CRITICAL(ENVONLY, buf, writeBuf, (status < 0) ? JNI_ABORT : 0); } @@ -1082,13 +1069,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) + H5Dvlen_reclaim(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) + H5Dvlen_reclaim(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; @@ -1099,7 +1518,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); @@ -1151,7 +1570,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 @@ -1303,54 +1722,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; @@ -1363,7 +1743,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); @@ -1415,7 +1795,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. @@ -1428,7 +1808,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; @@ -1500,7 +1880,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; @@ -1537,7 +1917,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); /* @@ -1548,11 +1928,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 @@ -1562,10 +1942,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) @@ -1573,7 +1953,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) { H5Dvlen_reclaim(tid, mem_space, xfer_plist_id, writeBuf); HDfree(writeBuf); @@ -1586,39 +1966,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 4568880..7de5a05 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -62,7 +62,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); @@ -210,10 +209,10 @@ h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_ /* Build default formats for long long types */ if (!fmt_llong[0]) { - if (HDsprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsprintf failure"); - if (HDsprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsprintf failure"); + if (HDsnprintf(fmt_llong, sizeof(fmt_llong), "%%%sd", H5_PRINTF_LL_WIDTH) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsnprintf failure"); + if (HDsnprintf(fmt_ullong, sizeof(fmt_ullong), "%%%su", H5_PRINTF_LL_WIDTH) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsnprintf failure"); } /* end if */ switch (tclass) { @@ -651,9 +650,8 @@ done: int h5str_sprint_reference(JNIEnv *env, h5str_t *out_str, hid_t region_obj, void *ref_buf) { - hid_t region = H5I_INVALID_HID; - char ref_name[1024]; - const char *path; + hid_t region = H5I_INVALID_HID; + char ref_name[1024]; int ret_value = FAIL; @@ -756,11 +754,12 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i HDmemcpy(&tmp_float, cptr, sizeof(float)); - if (NULL == (this_str = (char *)HDmalloc(25))) + size_t this_len = 25; + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%g", tmp_float) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%g", tmp_float) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); break; } @@ -770,11 +769,12 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i HDmemcpy(&tmp_double, cptr, sizeof(double)); - if (NULL == (this_str = (char *)HDmalloc(25))) + size_t this_len = 25; + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%g", tmp_double) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%g", tmp_double) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); break; } @@ -784,11 +784,12 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i HDmemcpy(&tmp_ldouble, cptr, sizeof(long double)); - if (NULL == (this_str = (char *)HDmalloc(27))) + size_t this_len = 27; + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%Lg", tmp_ldouble) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%Lg", tmp_ldouble) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); break; } @@ -850,25 +851,26 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i unsigned char tmp_uchar = 0; char tmp_char = 0; + size_t this_len = 7; if (H5T_SGN_NONE == nsign) { HDmemcpy(&tmp_uchar, cptr, sizeof(unsigned char)); - if (NULL == (this_str = (char *)HDmalloc(7))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%hhu", tmp_uchar) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%hhu", tmp_uchar) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } else { HDmemcpy(&tmp_char, cptr, sizeof(char)); - if (NULL == (this_str = (char *)HDmalloc(7))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%hhd", tmp_char) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%hhd", tmp_char) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } break; @@ -878,25 +880,26 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i unsigned short tmp_ushort = 0; short tmp_short = 0; + size_t this_len = 9; if (H5T_SGN_NONE == nsign) { HDmemcpy(&tmp_ushort, cptr, sizeof(unsigned short)); - if (NULL == (this_str = (char *)HDmalloc(9))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%hu", tmp_ushort) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%hu", tmp_ushort) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } else { HDmemcpy(&tmp_short, cptr, sizeof(short)); - if (NULL == (this_str = (char *)HDmalloc(9))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%hd", tmp_short) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%hd", tmp_short) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } break; @@ -906,25 +909,26 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i unsigned int tmp_uint = 0; int tmp_int = 0; + size_t this_len = 14; if (H5T_SGN_NONE == nsign) { HDmemcpy(&tmp_uint, cptr, sizeof(unsigned int)); - if (NULL == (this_str = (char *)HDmalloc(14))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%u", tmp_uint) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%u", tmp_uint) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } else { HDmemcpy(&tmp_int, cptr, sizeof(int)); - if (NULL == (this_str = (char *)HDmalloc(14))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%d", tmp_int) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%d", tmp_int) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } break; @@ -934,25 +938,26 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i unsigned long tmp_ulong = 0; long tmp_long = 0; + size_t this_len = 23; if (H5T_SGN_NONE == nsign) { HDmemcpy(&tmp_ulong, cptr, sizeof(unsigned long)); - if (NULL == (this_str = (char *)HDmalloc(23))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%lu", tmp_ulong) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%lu", tmp_ulong) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } else { HDmemcpy(&tmp_long, cptr, sizeof(long)); - if (NULL == (this_str = (char *)HDmalloc(23))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, "%ld", tmp_long) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%ld", tmp_long) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } break; @@ -963,25 +968,26 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i unsigned long long tmp_ullong = 0; long long tmp_llong = 0; + size_t this_len = 25; if (H5T_SGN_NONE == nsign) { HDmemcpy(&tmp_ullong, cptr, sizeof(unsigned long long)); - if (NULL == (this_str = (char *)HDmalloc(25))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, fmt_ullong, tmp_ullong) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, fmt_ullong, tmp_ullong) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } else { HDmemcpy(&tmp_llong, cptr, sizeof(long long)); - if (NULL == (this_str = (char *)HDmalloc(25))) + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - if (HDsprintf(this_str, fmt_llong, tmp_llong) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, fmt_llong, tmp_llong) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } break; @@ -1041,17 +1047,18 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i else { size_t i; - if (NULL == (this_str = (char *)HDmalloc(4 * (typeSize + 1)))) + size_t this_len = 4 * (typeSize + 1); + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (1 == typeSize) { - if (HDsprintf(this_str, "%#02x", ucptr[0]) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%#02x", ucptr[0]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } else { for (i = 0; i < typeSize; i++) - if (HDsprintf(this_str, "%s%02x", i ? ":" : "", ucptr[i]) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%s%02x", i ? ":" : "", ucptr[i]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } } @@ -1088,8 +1095,29 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i H5_LIBRARY_ERROR(ENVONLY); /* Print object data and close object */ - if (HDsprintf(this_str, "%u-%llu", (unsigned)oi.type, oi.addr) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + 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 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 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 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); @@ -1189,17 +1217,18 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i /* All other types get printed as hexadecimal */ - if (NULL == (this_str = (char *)HDmalloc(4 * (typeSize + 1)))) + size_t this_len = 4 * (typeSize + 1); + if (NULL == (this_str = (char *)HDmalloc(this_len))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); if (1 == typeSize) { - if (HDsprintf(this_str, "%#02x", ucptr[0]) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%#02x", ucptr[0]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } else { for (i = 0; i < typeSize; i++) - if (HDsprintf(this_str, "%s%02x", i ? ":" : "", ucptr[i]) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + if (HDsnprintf(this_str, this_len, "%s%02x", i ? ":" : "", ucptr[i]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure"); } break; @@ -1230,7 +1259,7 @@ done: * This is a special case subfunction to print the data in a region reference of type blocks. * * Return: - * The function returns FAIL if there was an error, otherwise SUCEED + * The function returns FAIL if there was an error, otherwise SUCCEED *------------------------------------------------------------------------- */ static int @@ -1401,8 +1430,9 @@ h5str_dump_region_blocks(JNIEnv *env, h5str_t *str, hid_t region_space, hid_t re for (j = 0; j < ndims; j++) { tmp_str[0] = '\0'; - if (HDsprintf(tmp_str, "%s%lu", j ? "," : "(", (unsigned long)ptdata[i * 2 * ndims + j]) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: HDsprintf failure"); + if (HDsnprintf(tmp_str, sizeof(tmp_str), "%s%lu", j ? "," : "(", + (unsigned long)ptdata[i * 2 * ndims + j]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: HDsnprintf failure"); if (!h5str_append(str, tmp_str)) H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); @@ -1411,9 +1441,9 @@ h5str_dump_region_blocks(JNIEnv *env, h5str_t *str, hid_t region_space, hid_t re for (j = 0; j < ndims; j++) { tmp_str[0] = '\0'; - if (HDsprintf(tmp_str, "%s%lu", j ? "," : ")-(", - (unsigned long)ptdata[i * 2 * ndims + j + ndims]) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: HDsprintf failure"); + if (HDsnprintf(tmp_str, sizeof(tmp_str), "%s%lu", j ? "," : ")-(", + (unsigned long)ptdata[i * 2 * ndims + j + ndims]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: HDsnprintf failure"); if (!h5str_append(str, tmp_str)) H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); @@ -1578,8 +1608,9 @@ h5str_dump_region_points(JNIEnv *env, h5str_t *str, hid_t region_space, hid_t re for (j = 0; j < ndims; j++) { tmp_str[0] = '\0'; - if (HDsprintf(tmp_str, "%s%lu", j ? "," : "(", (unsigned long)(ptdata[i * ndims + j])) < 0) - H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_points: HDsprintf failure"); + if (HDsnprintf(tmp_str, sizeof(tmp_str), "%s%lu", j ? "," : "(", + (unsigned long)(ptdata[i * ndims + j])) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_points: HDsnprintf failure"); if (!h5str_append(str, tmp_str)) H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); @@ -1628,7 +1659,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; @@ -1653,7 +1684,7 @@ done: * Purpose: Recursive check for variable length string of a datatype. * * Return: - * TRUE : type conatains any variable length string + * TRUE : type contains any variable length string * FALSE : type doesn't contain any variable length string * Negative value: error occur * @@ -2187,7 +2218,7 @@ done: * This is a special case subfunction to print the data in a region reference of type blocks. * * Return: - * The function returns FAIL if there was an error, otherwise SUCEED + * The function returns FAIL if there was an error, otherwise SUCCEED * *------------------------------------------------------------------------- */ @@ -2838,29 +2869,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 b7f12bd..9517630 100644 --- a/java/src/jni/h5util.h +++ b/java/src/jni/h5util.h @@ -39,6 +39,7 @@ 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_reference(JNIEnv *env, h5str_t *out_str, hid_t region_obj, void *ref_buf); |