diff options
author | Jordan Henderson <jhenderson@hdfgroup.org> | 2018-07-03 14:57:13 (GMT) |
---|---|---|
committer | Jordan Henderson <jhenderson@hdfgroup.org> | 2018-07-03 14:57:13 (GMT) |
commit | 6190641722e194f8827a5a68dce72dadac4b8157 (patch) | |
tree | 3e5751102492f2380c1e44bf3e91b3ac9c1af6eb /java/src/jni/h5aImp.c | |
parent | 8da8a1dcb5d1f51654018527fbc3fc9baeff130e (diff) | |
parent | b6fcbf4bb0f693fd6a0517f0ff3f74d52b329d1e (diff) | |
download | hdf5-6190641722e194f8827a5a68dce72dadac4b8157.zip hdf5-6190641722e194f8827a5a68dce72dadac4b8157.tar.gz hdf5-6190641722e194f8827a5a68dce72dadac4b8157.tar.bz2 |
Merging in latest from upstream (HDFFV/hdf5:refs/heads/develop)
* commit 'b6fcbf4bb0f693fd6a0517f0ff3f74d52b329d1e': (400 commits)
Fix ptr arith
Correct function call
Remove writeVL option
Region reference in compounds need class check
Correct cast formatting
Correct var name
Need to cast from void ptr
Update Java util lib, Refactor H5D write VL to match read
Fix attribute Read
Correct "," handling
Revert "Merge pull request #1116 in HDFFV/hdf5 from ~HDFTEST/hdf5_hft:hdf5_1_10 to develop"
Snapshot version 1.10 release 3 (snap3)
Remove debug statements
Split/fix utility for vl types
fix whitespace
HDFVIEW compound vlen needed vlen_t size
Update documents
Update document
Update document
HDFFV-10433 Update file with fix for issues
...
Diffstat (limited to 'java/src/jni/h5aImp.c')
-rw-r--r-- | java/src/jni/h5aImp.c | 322 |
1 files changed, 321 insertions, 1 deletions
diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index 26ec4fc..13f5207 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -49,6 +49,10 @@ extern jobject visit_callback; /* Local Prototypes */ /********************/ +static herr_t H5AwriteVL_asstr (JNIEnv *env, hid_t attr_id, hid_t mem_id, jobjectArray buf); +static herr_t H5AwriteVL_str (JNIEnv *env, hid_t attr_id, hid_t mem_id, jobjectArray buf); +static herr_t H5AreadVL_asstr (JNIEnv *env, hid_t attr_id, hid_t mem_id, jobjectArray buf); +static herr_t H5AreadVL_str (JNIEnv *env, hid_t attr_id, hid_t mem_id, jobjectArray buf); static herr_t H5A_iterate_cb(hid_t g_id, const char *name, const H5A_info_t *info, void *op_data); @@ -178,7 +182,6 @@ Java_hdf_hdf5lib_H5_H5Aread } /* end if */ else { status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, byteP); - if (status < 0) { ENVPTR->ReleaseByteArrayElements(ENVPAR buf, byteP, JNI_ABORT); h5libraryError(env); @@ -194,6 +197,323 @@ Java_hdf_hdf5lib_H5_H5Aread /* * Class: hdf_hdf5lib_H5 + * Method: H5AwriteVL + * 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) +{ + herr_t status = -1; + htri_t isStr = 0; + htri_t isVlenStr = 0; + htri_t isComplex = 0; + + if (buf == NULL) { + h5nullArgument(env, "H5AwriteVL: buf is NULL"); + } /* end if */ + else { + isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING); + if (H5Tget_class((hid_t)mem_type_id) == H5T_COMPOUND) { + unsigned i; + int nm = H5Tget_nmembers(mem_type_id); + for(i = 0; i <nm; i++) { + hid_t nested_tid = H5Tget_member_type((hid_t)mem_type_id, i); + isComplex = H5Tdetect_class((hid_t)nested_tid, H5T_COMPOUND) || + H5Tdetect_class((hid_t)nested_tid, H5T_VLEN); + H5Tclose(nested_tid); + } + } + else if (H5Tget_class((hid_t)mem_type_id) == H5T_VLEN) { + isVlenStr = 1; /* strings created by H5Tvlen_create(H5T_C_S1) */ + } + if (isStr == 0 || isComplex>0 || isVlenStr) { + status = H5AwriteVL_asstr(env, (hid_t)attr_id, (hid_t)mem_type_id, buf); + } + else if (isStr > 0) { + status = H5AwriteVL_str(env, (hid_t)attr_id, (hid_t)mem_type_id, buf); + } + } /* end else */ + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Awrite_1VL */ + +herr_t +H5AwriteVL_str + (JNIEnv *env, hid_t aid, hid_t tid, jobjectArray buf) +{ + herr_t status = -1; + char **wdata; + jsize size; + jint i; + + size = ENVPTR->GetArrayLength(ENVPAR (jarray) buf); + + wdata = (char**)HDcalloc((size_t)size + 1, sizeof(char*)); + if (!wdata) { + h5JNIFatalError(env, "H5AwriteVL_str: cannot allocate buffer"); + } /* end if */ + else { + HDmemset(wdata, 0, (size_t)size * sizeof(char*)); + for (i = 0; i < size; ++i) { + jstring obj = (jstring) ENVPTR->GetObjectArrayElement(ENVPAR (jobjectArray) buf, i); + if (obj != 0) { + jsize length = ENVPTR->GetStringUTFLength(ENVPAR obj); + const char *utf8 = ENVPTR->GetStringUTFChars(ENVPAR obj, 0); + + if (utf8) { + wdata[i] = (char*)HDmalloc((size_t)length + 1); + if (wdata[i]) { + HDmemset(wdata[i], 0, ((size_t)length + 1)); + HDstrncpy(wdata[i], utf8, (size_t)length); + } /* end if */ + } /* end if */ + + ENVPTR->ReleaseStringUTFChars(ENVPAR obj, utf8); + ENVPTR->DeleteLocalRef(ENVPAR obj); + } /* end if */ + } /* end for (i = 0; i < size; ++i) */ + + status = H5Awrite((hid_t)aid, (hid_t)tid, wdata); + + for (i = 0; i < size; i++) { + if(wdata[i]) { + HDfree(wdata[i]); + } /* end if */ + } /* end for */ + HDfree(wdata); + + if (status < 0) + h5libraryError(env); + } /* end else */ + + return (jint)status; +} + +herr_t +H5AwriteVL_asstr + (JNIEnv *env, hid_t aid, hid_t tid, jobjectArray buf) +{ + char **strs; + jstring jstr; + jint i; + jint n; + hid_t sid; + hsize_t dims[H5S_MAX_RANK]; + herr_t status = -1; + + n = ENVPTR->GetArrayLength(ENVPAR buf); + strs =(hvl_t*)HDcalloc((size_t)n, sizeof(hvl_t)); + + if (strs == NULL) { + h5JNIFatalError(env, "H5AwriteVL_asstr: failed to allocate buff for read variable length strings"); + } /* end if */ + else { + status = H5Awrite(aid, tid, strs); + + if (status < 0) { + dims[0] = (hsize_t)n; + sid = H5Screate_simple(1, dims, NULL); + H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, strs); + H5Sclose(sid); + HDfree(strs); + h5JNIFatalError(env, "H5AwriteVL_str: failed to read variable length strings"); + } /* end if */ + else { + for (i=0; i < n; i++) { + jstr = ENVPTR->NewStringUTF(ENVPAR strs[i]); + ENVPTR->SetObjectArrayElement(ENVPAR buf, i, jstr); + H5free_memory (strs[i]); + } /* end for */ + + /* + for repeatedly reading a dataset with a large number of strs (e.g., 1,000,000 strings, + H5Dvlen_reclaim() may crash on Windows because the Java GC will not be able to collect + free space in time. Instead, use "H5free_memory(strs[i])" above to free individual strings + after it is done. + H5Dvlen_reclaim(tid, mem_sid, xfer_plist_id, strs); + */ + + HDfree(strs); + } /* end else */ + } /* end else */ + + return status; +} /* end H5AwriteVL_str */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5AreadVL + * Signature: (JJJJJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5AreadVL + (JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) +{ + herr_t status = -1; + htri_t isStr = 0; + htri_t isVlenStr = 0; + htri_t isComplex = 0; + + if (buf == NULL) { + h5nullArgument(env, "H5AreadVL: buf is NULL"); + } /* end if */ + else { + isStr = H5Tdetect_class((hid_t)mem_type_id, H5T_STRING); + if (H5Tget_class((hid_t)mem_type_id) == H5T_COMPOUND) { + unsigned i; + int nm = H5Tget_nmembers(mem_type_id); + for(i = 0; i <nm; i++) { + hid_t nested_tid = H5Tget_member_type((hid_t)mem_type_id, i); + isComplex = H5Tdetect_class((hid_t)nested_tid, H5T_COMPOUND) || + H5Tdetect_class((hid_t)nested_tid, H5T_VLEN); + H5Tclose(nested_tid); + } + } + else if (H5Tget_class((hid_t)mem_type_id) == H5T_VLEN) { + isVlenStr = 1; /* strings created by H5Tvlen_create(H5T_C_S1) */ + } + if (isStr == 0 || isComplex>0 || isVlenStr) { + status = H5AreadVL_asstr(env, (hid_t)attr_id, (hid_t)mem_type_id, buf); + } + else if (isStr > 0) { + status = H5AreadVL_str(env, (hid_t)attr_id, (hid_t)mem_type_id, buf); + } + } /* end else */ + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Aread_1VL */ + +herr_t +H5AreadVL_asstr + (JNIEnv *env, hid_t aid, hid_t tid, jobjectArray buf) +{ + jint i; + jint n; + hid_t sid; + jstring jstr; + h5str_t h5str; + hvl_t *rdata; + hsize_t dims[H5S_MAX_RANK]; + size_t size; + size_t max_len = 0; + herr_t status = -1; + + /* Get size of string array */ + n = ENVPTR->GetArrayLength(ENVPAR buf); + /* we will need to read n number of hvl_t structures */ + rdata = (hvl_t*)HDcalloc((size_t)n, sizeof(hvl_t)); + if (rdata == NULL) { + h5JNIFatalError(env, "H5AreadVL_asstr: failed to allocate buff for read"); + } /* end if */ + else { + status = H5Aread(aid, tid, rdata); + + if (status < 0) { + dims[0] = (hsize_t)n; + sid = H5Screate_simple(1, dims, NULL); + H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rdata); + H5Sclose(sid); + HDfree(rdata); + h5JNIFatalError(env, "H5AreadVL_asstr: failed to read data"); + } /* end if */ + else { + /* calculate the largest size of all the hvl_t structures read */ + max_len = 1; + for (i=0; i < n; i++) { + if ((rdata + i)->len > max_len) + max_len = (rdata + i)->len; + } + + /* create one malloc to hold largest element */ + size = H5Tget_size(tid) * max_len; + HDmemset(&h5str, 0, sizeof(h5str_t)); + h5str_new(&h5str, 4 * size); + + if (h5str.s == NULL) { + dims[0] = (hsize_t)n; + sid = H5Screate_simple(1, dims, NULL); + H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rdata); + H5Sclose(sid); + HDfree(rdata); + h5JNIFatalError(env, "H5AreadVL_asstr: failed to allocate buf"); + } /* end if */ + else { + H5T_class_t tclass = H5Tget_class(tid); + /* convert each element to char string */ + for (i=0; i < n; i++) { + h5str.s[0] = '\0'; + h5str_vlsprintf(&h5str, aid, tid, rdata+i, 0); + jstr = ENVPTR->NewStringUTF(ENVPAR h5str.s); + ENVPTR->SetObjectArrayElement(ENVPAR buf, i, jstr); + } /* end for */ + h5str_free(&h5str); + + dims[0] = (hsize_t)n; + sid = H5Screate_simple(1, dims, NULL); + H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rdata); + H5Sclose(sid); + HDfree(rdata); + } /* end else */ + } /* end else */ + } /* end else */ + + return status; +} + +herr_t +H5AreadVL_str + (JNIEnv *env, hid_t aid, hid_t tid, jobjectArray buf) +{ + char **strs; + jstring jstr; + jint i; + jint n; + hid_t sid; + hsize_t dims[H5S_MAX_RANK]; + herr_t status = -1; + + n = ENVPTR->GetArrayLength(ENVPAR buf); + strs =(char**)HDcalloc((size_t)n, sizeof(char*)); + + if (strs == NULL) { + h5JNIFatalError(env, "H5AreadVL_str: failed to allocate buff for read variable length strings"); + } /* end if */ + else { + status = H5Aread(aid, tid, strs); + + if (status < 0) { + dims[0] = (hsize_t)n; + sid = H5Screate_simple(1, dims, NULL); + H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, strs); + H5Sclose(sid); + HDfree(strs); + h5JNIFatalError(env, "H5AreadVL_str: failed to read variable length strings"); + } /* end if */ + else { + for (i=0; i < n; i++) { + jstr = ENVPTR->NewStringUTF(ENVPAR strs[i]); + ENVPTR->SetObjectArrayElement(ENVPAR buf, i, jstr); + H5free_memory (strs[i]); + } /* end for */ + + /* + for repeatedly reading a dataset with a large number of strs (e.g., 1,000,000 strings, + H5Dvlen_reclaim() may crash on Windows because the Java GC will not be able to collect + free space in time. Instead, use "H5free_memory(strs[i])" above to free individual strings + after it is done. + H5Dvlen_reclaim(tid, mem_sid, xfer_plist_id, strs); + */ + + HDfree(strs); + } /* end else */ + } /* end else */ + + return status; +} /* end H5AreadVL_str */ + +/* + * Class: hdf_hdf5lib_H5 * Method: H5Aget_space * Signature: (J)J */ |