summaryrefslogtreecommitdiffstats
path: root/java/src/jni/h5util.c
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/jni/h5util.c')
-rw-r--r--java/src/jni/h5util.c4948
1 files changed, 4948 insertions, 0 deletions
diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c
new file mode 100644
index 0000000..77fb244
--- /dev/null
+++ b/java/src/jni/h5util.c
@@ -0,0 +1,4948 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * For details of the HDF libraries, see the HDF Documentation at:
+ * http://hdfgroup.org/HDF5/doc/
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <jni.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "hdf5.h"
+#include "h5util.h"
+
+/* size of hyperslab buffer when a dataset is bigger than H5TOOLS_MALLOCSIZE */
+hsize_t H5TOOLS_BUFSIZE = (32 * 1024 * 1024); /* 32 MB */
+int H5TOOLS_TEXT_BLOCK = 16; /* Number of elements on a line in a text export file */
+
+/*
+ * Pointer to the JNI's Virtual Machine; used for callback functions.
+ */
+JavaVM *jvm;
+
+jobject copy_callback;
+jobject close_callback;
+jobject create_callback;
+jobject compare_callback;
+jobject get_callback;
+jobject set_callback;
+jobject delete_callback;
+
+H5E_auto2_t efunc;
+void *edata;
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+int h5str_old_region_dataset(JNIEnv *env, h5str_t *out_str, hid_t container, void *ref_buf, int expand_data);
+int h5str_region_dataset(JNIEnv *env, h5str_t *out_str, H5R_ref_t *ref_vp, int expand_data);
+
+static int h5str_dump_region_blocks(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj,
+ int expand_data);
+static int h5str_dump_region_points(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj,
+ int expand_data);
+static int h5str_dump_region_attribute(JNIEnv *env, h5str_t *str, hid_t region_id);
+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_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);
+static int h5str_render_bin_output(FILE *stream, hid_t container, hid_t tid, void *_mem,
+ hsize_t block_nelmts);
+static int render_bin_output_region_data_blocks(FILE *stream, hid_t region_id, hid_t container, int ndims,
+ hid_t type_id, hssize_t nblocks, hsize_t *ptdata);
+static int render_bin_output_region_blocks(FILE *stream, hid_t region_space, hid_t region_id,
+ hid_t container);
+static int render_bin_output_region_data_points(FILE *stream, hid_t region_space, hid_t region_id,
+ hid_t container, int ndims, hid_t type_id, hssize_t npoints,
+ hsize_t *ptdata);
+static int render_bin_output_region_points(FILE *stream, hid_t region_space, hid_t region_id,
+ hid_t container);
+jobject translate_atomic_rbuf(JNIEnv *env, jobject ret_buf, jlong mem_type_id, H5T_class_t type_class,
+ void *raw_buf);
+void translate_atomic_wbuf(JNIEnv *env, jobject in_obj, jlong mem_type_id, H5T_class_t type_class,
+ void *raw_buf);
+
+/* Strings for output */
+#define H5_TOOLS_GROUP "GROUP"
+#define H5_TOOLS_DATASET "DATASET"
+#define H5_TOOLS_DATATYPE "DATATYPE"
+#define H5_TOOLS_ATTRIBUTE "ATTRIBUTE"
+
+/** frees memory held by array of strings */
+void
+h5str_array_free(char **strs, size_t len)
+{
+ size_t i;
+
+ if (!strs || len <= 0)
+ return;
+
+ for (i = 0; i < len; i++) {
+ if (strs[i])
+ HDfree(strs[i]);
+ } /* for (i=0; i<n; i++)*/
+
+ HDfree(strs);
+} /* end h5str_array_free */
+
+/** allocate a new str with given length */
+void
+h5str_new(h5str_t *str, size_t len)
+{
+ if (str && len > 0) {
+ str->s = (char *)HDmalloc(len);
+ str->max = len;
+ str->s[0] = '\0';
+ } /* end if */
+} /* end h5str_new */
+
+/** free string memory */
+void
+h5str_free(h5str_t *str)
+{
+ if (str && str->max > 0) {
+ HDfree(str->s);
+ HDmemset(str, 0, sizeof(h5str_t));
+ } /* end if */
+} /* end h5str_free */
+
+/** reset the max size of the string */
+/*
+ * TODO: no error return. malloc can fail.
+ */
+void
+h5str_resize(h5str_t *str, size_t new_len)
+{
+ char *new_str;
+
+ if (!str || new_len <= 0 || str->max == new_len)
+ return;
+
+ if (NULL == (new_str = (char *)HDmalloc(new_len)))
+ return;
+
+ if (new_len > str->max) /* increase memory */
+ HDstrcpy(new_str, str->s);
+ else
+ HDstrncpy(new_str, str->s, new_len - 1);
+
+ HDfree(str->s);
+ str->s = new_str;
+ str->max = new_len;
+} /* end h5str_resize */
+
+/* appends a copy of the string pointed to by cstr to the h5str.
+ Return Value:
+ the char string point to str->s
+ */
+char *
+h5str_append(h5str_t *str, const char *cstr)
+{
+ size_t len;
+
+ if (!str)
+ return NULL;
+ else if (!cstr)
+ return str->s;
+
+ len = HDstrlen(str->s) + HDstrlen(cstr);
+ while (len >= str->max) /* not enough to hold the new string, double the space */
+ {
+ h5str_resize(str, str->max * 2);
+ }
+
+ return HDstrcat(str->s, cstr);
+} /* end h5str_append */
+
+/*
+ * Converts the given data point string into a real data point.
+ *
+ * Returns:
+ * SUCCESS: Length of string token processed
+ * FAILURE: 0
+ */
+size_t
+h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_buf, size_t out_buf_offset)
+{
+ unsigned char *ucptr = NULL;
+ char fmt_llong[8], fmt_ullong[8];
+ H5T_class_t tclass = H5T_NO_CLASS;
+ const char delimiter[] = " ," H5_COMPOUND_BEGIN_INDICATOR H5_COMPOUND_END_INDICATOR
+ H5_ARRAY_BEGIN_INDICATOR H5_ARRAY_END_INDICATOR H5_VLEN_BEGIN_INDICATOR H5_VLEN_END_INDICATOR;
+
+ size_t retVal = 0;
+ size_t typeSize = 0;
+ hid_t mtid = H5I_INVALID_HID;
+ char *this_str = NULL;
+ char *cptr = NULL;
+ char *token;
+ int n;
+
+ if (!in_str)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_convert: in_str is NULL");
+ if (!out_buf)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_convert: out_buf is NULL");
+
+ this_str = *in_str;
+ cptr = &(((char *)out_buf)[out_buf_offset]);
+ ucptr = &(((unsigned char *)out_buf)[out_buf_offset]);
+
+ if (H5T_NO_CLASS == (tclass = H5Tget_class(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(typeSize = H5Tget_size(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Build default formats for long long types */
+ if (!fmt_llong[0]) {
+ if (HDsnprintf(fmt_llong, sizeof(fmt_llong), "%%lld") < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsnprintf failure");
+ if (HDsnprintf(fmt_ullong, sizeof(fmt_ullong), "%%llu") < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsnprintf failure");
+ } /* end if */
+
+ switch (tclass) {
+ case H5T_FLOAT: {
+ token = HDstrtok(this_str, delimiter);
+
+ switch (typeSize) {
+ case sizeof(float): {
+ float tmp_float = 0.0f;
+
+ HDsscanf(token, "%f", &tmp_float);
+ HDmemcpy(cptr, &tmp_float, sizeof(float));
+ break;
+ }
+
+ case sizeof(double): {
+ double tmp_double = 0.0;
+
+ HDsscanf(token, "%lf", &tmp_double);
+ HDmemcpy(cptr, &tmp_double, sizeof(double));
+ break;
+ }
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+ case sizeof(long double): {
+ long double tmp_ldouble = 0.0;
+
+ HDsscanf(token, "%Lg", &tmp_ldouble);
+ HDmemcpy(cptr, &tmp_ldouble, sizeof(long double));
+ break;
+ }
+#endif
+
+ default:
+ H5_BAD_ARGUMENT_ERROR(
+ ENVONLY,
+ "h5str_convert: floating-point datatype size didn't match any of expected sizes");
+ break;
+ }
+
+ retVal = typeSize;
+
+ break;
+ }
+
+ case H5T_STRING: {
+ size_t len = HDstrlen(this_str);
+
+ if (len > 0) {
+ HDstrncpy(cptr, this_str, typeSize);
+ cptr[typeSize - 1] = '\0';
+
+ retVal = typeSize;
+ }
+ else {
+ cptr = NULL;
+ }
+
+ break;
+ }
+
+ case H5T_INTEGER: {
+ H5T_sign_t nsign = H5T_SGN_ERROR;
+
+ if (H5T_SGN_ERROR == (nsign = H5Tget_sign(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ token = HDstrtok(this_str, delimiter);
+
+ switch (typeSize) {
+ case sizeof(char): {
+ unsigned char tmp_uchar = 0;
+ signed char tmp_char = 0;
+
+ if (H5T_SGN_NONE == nsign) {
+ HDsscanf(token, "%hhu", &tmp_uchar);
+ HDmemcpy(cptr, &tmp_uchar, sizeof(unsigned char));
+ }
+ else {
+ HDsscanf(token, "%hhd", &tmp_char);
+ HDmemcpy(cptr, &tmp_char, sizeof(char));
+ }
+
+ break;
+ }
+
+ case sizeof(short): {
+ unsigned short tmp_ushort = 0;
+ short tmp_short = 0;
+
+ if (H5T_SGN_NONE == nsign) {
+ HDsscanf(token, "%hu", &tmp_ushort);
+ HDmemcpy(&tmp_ushort, cptr, sizeof(unsigned short));
+ }
+ else {
+ HDsscanf(token, "%hd", &tmp_short);
+ HDmemcpy(&tmp_short, cptr, sizeof(short));
+ }
+
+ break;
+ }
+
+ case sizeof(int): {
+ unsigned int tmp_uint = 0;
+ int tmp_int = 0;
+
+ if (H5T_SGN_NONE == nsign) {
+ HDsscanf(token, "%u", &tmp_uint);
+ HDmemcpy(cptr, &tmp_uint, sizeof(unsigned int));
+ }
+ else {
+ HDsscanf(token, "%d", &tmp_int);
+ HDmemcpy(cptr, &tmp_int, sizeof(int));
+ }
+
+ break;
+ }
+
+#if H5_SIZEOF_LONG != H5_SIZEOF_INT
+ case sizeof(long): {
+ unsigned long tmp_ulong = 0;
+ long tmp_long = 0;
+
+ if (H5T_SGN_NONE == nsign) {
+ HDsscanf(token, "%lu", &tmp_ulong);
+ HDmemcpy(cptr, &tmp_ulong, sizeof(unsigned long));
+ }
+ else {
+ HDsscanf(token, "%ld", &tmp_long);
+ HDmemcpy(cptr, &tmp_long, sizeof(long));
+ }
+
+ break;
+ }
+#endif
+#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG
+ case sizeof(long long): {
+ unsigned long long tmp_ullong = 0;
+ long long tmp_llong = 0;
+
+ if (H5T_SGN_NONE == nsign) {
+ HDsscanf(token, fmt_ullong, &tmp_ullong);
+ HDmemcpy(cptr, &tmp_ullong, sizeof(unsigned long long));
+ }
+ else {
+ HDsscanf(token, fmt_llong, &tmp_llong);
+ HDmemcpy(cptr, &tmp_llong, sizeof(long long));
+ }
+
+ break;
+ }
+#endif
+
+ default:
+ H5_BAD_ARGUMENT_ERROR(
+ ENVONLY, "h5str_convert: integer datatype size didn't match any of expected sizes");
+ break;
+ }
+
+ retVal = typeSize;
+
+ break;
+ }
+
+ case H5T_COMPOUND: {
+ unsigned i;
+ size_t member_offset;
+
+ if ((n = H5Tget_nmembers(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Skip whitespace and compound indicators */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == '{')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+
+ for (i = 0; i < (unsigned)n; i++) {
+ member_offset = H5Tget_member_offset(tid, i);
+
+ if ((mtid = H5Tget_member_type(tid, i)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!h5str_convert(ENVONLY, &this_str, container, mtid, out_buf, member_offset)) {
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ goto done;
+ }
+
+ /* Skip whitespace and commas */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == ',')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+
+ if (H5Tclose(mtid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ mtid = H5I_INVALID_HID;
+ }
+
+ /* Skip whitespace and compound indicators */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == '}')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+
+ retVal = typeSize * (size_t)n;
+
+ break;
+ }
+
+ /* TODO handle reference writing */
+ case H5T_REFERENCE:
+ cptr = NULL;
+ break;
+
+ case H5T_ENUM: {
+ void *value = NULL;
+
+ token = HDstrtok(this_str, delimiter);
+
+ switch (typeSize) {
+ case sizeof(char): {
+ unsigned char tmp_uchar = 0;
+ value = &tmp_uchar;
+ break;
+ }
+
+ case sizeof(short): {
+ unsigned short tmp_ushort = 0;
+ value = &tmp_ushort;
+ break;
+ }
+#if H5_SIZEOF_LONG != H5_SIZEOF_INT
+ case sizeof(long): {
+ unsigned long tmp_ulong = 0;
+ value = &tmp_ulong;
+ break;
+ }
+#endif
+#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG
+ case sizeof(long long): {
+ unsigned long long tmp_ullong = 0;
+ value = &tmp_ullong;
+ break;
+ }
+#endif
+
+ default: {
+ unsigned int tmp_uint = 0;
+ value = &tmp_uint;
+ break;
+ }
+ }
+
+ if (H5Tenum_valueof(tid, token, value) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ HDmemcpy(ucptr, value, typeSize);
+
+ retVal = typeSize;
+
+ break;
+ }
+
+ case H5T_ARRAY: {
+ hsize_t i, dims[H5S_MAX_RANK], total_elmts;
+ size_t baseTypeSize;
+ int rank = 0;
+
+ /* Skip whitespace and array indicators */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == '[')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+
+ if ((mtid = H5Tget_super(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!(baseTypeSize = H5Tget_size(mtid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((rank = H5Tget_array_ndims(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Tget_array_dims2(tid, dims) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ for (i = 0, total_elmts = 1; i < (hsize_t)rank; i++)
+ total_elmts *= dims[i];
+
+ if (NULL == (cptr = (char *)HDcalloc((size_t)total_elmts, baseTypeSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_convert: failed to allocate array buffer");
+
+ for (i = 0; i < total_elmts; i++) {
+ if (!(h5str_convert(ENVONLY, &this_str, container, mtid, out_buf, i * baseTypeSize))) {
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ goto done;
+ }
+
+ /* Skip whitespace and commas */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == ',')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+ }
+
+ if (H5Tclose(mtid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ mtid = H5I_INVALID_HID;
+
+ /* Skip whitespace and array indicators */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == ']')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+
+ retVal = typeSize * total_elmts;
+
+ break;
+ }
+
+ case H5T_VLEN: {
+ size_t i, baseTypeSize;
+ hvl_t *vl_buf = (hvl_t *)out_buf;
+ char cur_char;
+
+ if ((mtid = H5Tget_super(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!(baseTypeSize = H5Tget_size(mtid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (NULL == (vl_buf->p = HDmalloc(baseTypeSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_convert: failed to allocate vlen buffer");
+ vl_buf->len = 1;
+
+ /* Skip whitespace and vlen indicators */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == '(')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+
+ cur_char = *this_str;
+ for (i = 0; cur_char != ')' && cur_char != '\0'; i++) {
+ if (i >= vl_buf->len) {
+ char *tmp_realloc;
+
+ if (NULL == (tmp_realloc = (char *)HDrealloc(vl_buf->p, vl_buf->len * 2 * baseTypeSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_convert: failed to reallocate vlen buffer");
+ vl_buf->len *= 2;
+ vl_buf->p = tmp_realloc;
+ }
+
+ if (!(h5str_convert(ENVONLY, &this_str, container, mtid, vl_buf->p, i * baseTypeSize))) {
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ vl_buf->len = i;
+ goto done;
+ }
+
+ /* Skip whitespace and commas */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == ',')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+ }
+
+ vl_buf->len = i;
+
+ if (H5Tclose(mtid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ mtid = H5I_INVALID_HID;
+
+ /* Skip whitespace and vlen indicators */
+ while (*this_str == ' ')
+ this_str++;
+ if (*this_str == ')')
+ this_str++;
+ while (*this_str == ' ')
+ this_str++;
+
+ retVal = typeSize;
+
+ break;
+ }
+
+ case H5T_NCLASSES:
+ case H5T_NO_CLASS: {
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_convert: invalid datatype class");
+ break;
+ }
+
+ case H5T_TIME:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ default: {
+ /* All other types get copied raw */
+ HDmemcpy(ucptr, this_str, typeSize);
+
+ retVal = typeSize;
+
+ break;
+ }
+ } /* end switch */
+
+done:
+ if (mtid >= 0)
+ H5Tclose(mtid);
+
+ return retVal;
+} /* end h5str_convert */
+
+/*-------------------------------------------------------------------------
+ * Function: h5str_sprint_old_reference
+ *
+ * Purpose: Object reference -- show the name of the 1.10 referenced object.
+ *
+ * Return: SUCCEED or FAIL
+ *-------------------------------------------------------------------------
+ */
+int
+h5str_sprint_old_reference(JNIEnv *env, h5str_t *out_str, hid_t region_obj, void *ref_buf)
+{
+ char ref_name[1024];
+ int ret_value = FAIL;
+
+ if ((H5Rget_name(region_obj, H5R_DATASET_REGION, ref_buf, (char *)ref_name, 1024)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!h5str_append(out_str, ref_name))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ ret_value = SUCCEED;
+
+done:
+ return ret_value;
+} /* h5str_sprint_reference */
+
+/*-------------------------------------------------------------------------
+ * Function: h5str_sprint_reference
+ *
+ * Purpose: Object reference -- show the name of the referenced object.
+ *
+ * Return: SUCCEED or FAIL
+ *-------------------------------------------------------------------------
+ */
+int
+h5str_sprint_reference(JNIEnv *env, h5str_t *out_str, void *ref_p)
+{
+ ssize_t buf_size;
+ char *ref_name = NULL;
+ H5R_ref_t *ref_vp = (H5R_ref_t *)ref_p;
+
+ int ret_value = FAIL;
+
+ buf_size = H5Rget_file_name(ref_vp, NULL, 0);
+ if (buf_size > 0) {
+ ref_name = (char *)HDmalloc(sizeof(char) * (size_t)buf_size + 1);
+ if (H5Rget_file_name(ref_vp, ref_name, (size_t)buf_size + 1) >= 0) {
+ ref_name[buf_size] = '\0';
+ if (!h5str_append(out_str, ref_name))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+ HDfree(ref_name);
+ ref_name = NULL;
+ }
+
+ buf_size = H5Rget_obj_name(ref_vp, H5P_DEFAULT, NULL, 0);
+ if (buf_size > 0) {
+ ref_name = (char *)HDmalloc(sizeof(char) * (size_t)buf_size + 1);
+ if (H5Rget_obj_name(ref_vp, H5P_DEFAULT, ref_name, (size_t)buf_size + 1) >= 0) {
+ ref_name[buf_size] = '\0';
+ if (!h5str_append(out_str, ref_name))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+ HDfree(ref_name);
+ ref_name = NULL;
+ }
+
+ if (H5Rget_type(ref_vp) == H5R_ATTR) {
+ buf_size = H5Rget_attr_name(ref_vp, NULL, 0);
+ if (buf_size > 0) {
+ ref_name = (char *)HDmalloc(sizeof(char) * (size_t)buf_size + 1);
+ if (H5Rget_attr_name(ref_vp, ref_name, (size_t)buf_size + 1) >= 0) {
+ ref_name[buf_size] = '\0';
+ if (!h5str_append(out_str, ref_name))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+ HDfree(ref_name);
+ ref_name = NULL;
+ }
+ }
+
+ ret_value = SUCCEED;
+done:
+ if (ref_name)
+ HDfree(ref_name);
+
+ return ret_value;
+} /* h5str_sprint_reference */
+
+int
+h5str_old_region_dataset(JNIEnv *env, h5str_t *out_str, hid_t container, void *ref_buf, int expand_data)
+{
+ H5S_sel_type region_type = H5S_SEL_ERROR;
+ hid_t region_obj = H5I_INVALID_HID;
+ hid_t region_sid = H5I_INVALID_HID;
+
+ int ret_value = FAIL;
+
+ if ((region_obj = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, ref_buf)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((region_sid = H5Rget_region(container, H5R_DATASET_REGION, ref_buf)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (expand_data == 0)
+ if (h5str_sprint_old_reference(ENVONLY, out_str, region_obj, ref_buf) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if ((region_type = H5Sget_select_type(region_sid)) > H5S_SEL_ERROR) {
+ if (H5S_SEL_POINTS == region_type) {
+ if (h5str_dump_region_points(ENVONLY, out_str, region_sid, region_obj, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else if (H5S_SEL_HYPERSLABS == region_type) {
+ if (h5str_dump_region_blocks(ENVONLY, out_str, region_sid, region_obj, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ }
+
+ ret_value = SUCCEED;
+done:
+ if (region_sid >= 0)
+ if (H5Sclose(region_sid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (region_obj >= 0)
+ if (H5Dclose(region_obj) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ return ret_value;
+}
+
+int
+h5str_region_dataset(JNIEnv *env, h5str_t *out_str, H5R_ref_t *ref_vp, int expand_data)
+{
+ hid_t new_obj_id = H5I_INVALID_HID;
+ hid_t new_obj_sid = H5I_INVALID_HID;
+ H5S_sel_type region_type;
+
+ int ret_value = FAIL;
+
+ if ((new_obj_id = H5Ropen_object(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ ret_value = SUCCEED; /* An uncreated region is a valid state */
+ goto done;
+ }
+
+ if ((new_obj_sid = H5Ropen_region(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (expand_data == 0)
+ if (h5str_sprint_reference(ENVONLY, out_str, ref_vp) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if ((region_type = H5Sget_select_type(new_obj_sid)) > H5S_SEL_ERROR) {
+ if (H5S_SEL_POINTS == region_type) {
+ if (h5str_dump_region_points(ENVONLY, out_str, new_obj_sid, new_obj_id, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else if (H5S_SEL_HYPERSLABS == region_type) {
+ if (h5str_dump_region_blocks(ENVONLY, out_str, new_obj_sid, new_obj_id, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ }
+
+ ret_value = SUCCEED;
+done:
+ if (new_obj_sid >= 0)
+ if (H5Sclose(new_obj_sid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (new_obj_id >= 0)
+ if (H5Dclose(new_obj_id) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ return ret_value;
+}
+
+/*
+ * Prints the value of a data point into a string.
+ *
+ * Returns:
+ * SUCCESS: Total number of characters printed
+ * FAILURE: 0
+ */
+size_t
+h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *in_buf, int expand_data)
+{
+ unsigned char *ucptr = (unsigned char *)in_buf;
+ char fmt_llong[8], fmt_ullong[8];
+ H5T_class_t tclass = H5T_NO_CLASS;
+ size_t typeSize = 0;
+ H5T_sign_t nsign = H5T_SGN_ERROR;
+ hid_t mtid = H5I_INVALID_HID;
+ char *cptr = (char *)in_buf;
+ char *this_str = NULL;
+ int n;
+ size_t retVal = 0;
+
+ if (!out_str)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: out_str is NULL");
+ if (!in_buf)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: in_buf is NULL");
+
+ if (H5T_NO_CLASS == (tclass = H5Tget_class(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(typeSize = H5Tget_size(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Build default formats for long long types */
+ if (!fmt_llong[0]) {
+ if (HDsnprintf(fmt_llong, sizeof(fmt_llong), "%%lld") < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ if (HDsnprintf(fmt_ullong, sizeof(fmt_ullong), "%%llu") < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ } /* end if */
+ switch (tclass) {
+ case H5T_FLOAT: {
+ switch (typeSize) {
+ case sizeof(float): {
+ float tmp_float = 0.0f;
+
+ HDmemcpy(&tmp_float, cptr, sizeof(float));
+
+ 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 (HDsnprintf(this_str, this_len, "%g", (double)tmp_float) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+
+ break;
+ }
+
+ case sizeof(double): {
+ double tmp_double = 0.0;
+
+ HDmemcpy(&tmp_double, cptr, sizeof(double));
+
+ 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 (HDsnprintf(this_str, this_len, "%g", tmp_double) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+
+ break;
+ }
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+ case sizeof(long double): {
+ long double tmp_ldouble = 0.0;
+
+ HDmemcpy(&tmp_ldouble, cptr, sizeof(long double));
+
+ 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 (HDsnprintf(this_str, this_len, "%Lg", tmp_ldouble) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+
+ break;
+ }
+#endif
+
+ default:
+ H5_BAD_ARGUMENT_ERROR(
+ ENVONLY,
+ "h5str_sprintf: floating-point datatype size didn't match any of expected sizes");
+ break;
+ }
+
+ break;
+ }
+
+ case H5T_STRING: {
+ htri_t is_variable;
+ char *tmp_str;
+
+ typeSize = 0;
+
+ if ((is_variable = H5Tis_variable_str(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (is_variable) {
+ /* cp_vp is the pointer into the struct where a `char*' is stored. So we have
+ * to dereference the pointer to get the `char*' to pass to HDstrlen(). */
+ tmp_str = *(char **)in_buf;
+ if (NULL != tmp_str)
+ typeSize = HDstrlen(tmp_str);
+ }
+ else {
+ tmp_str = cptr;
+ }
+
+ /* Check for NULL pointer for string */
+ if (!tmp_str) {
+ if (NULL == (this_str = (char *)HDmalloc(5)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer");
+ HDstrncpy(this_str, "NULL", 5);
+ }
+ else {
+ if (typeSize > 0) {
+ if (NULL == (this_str = HDstrdup(tmp_str)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer");
+ }
+ }
+
+ break;
+ }
+
+ case H5T_INTEGER: {
+
+ if (H5T_SGN_ERROR == (nsign = H5Tget_sign(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ switch (typeSize) {
+ case sizeof(char): {
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ if (HDsnprintf(this_str, this_len, "%hhd", tmp_char) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ }
+
+ break;
+ }
+
+ case sizeof(short): {
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ if (HDsnprintf(this_str, this_len, "%hd", tmp_short) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ }
+
+ break;
+ }
+
+ case sizeof(int): {
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ if (HDsnprintf(this_str, this_len, "%d", tmp_int) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ }
+
+ break;
+ }
+#if H5_SIZEOF_LONG != H5_SIZEOF_INT
+ case sizeof(long): {
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ if (HDsnprintf(this_str, this_len, "%ld", tmp_long) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ }
+
+ break;
+ }
+#endif
+#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG
+ case sizeof(long long): {
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ 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(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+
+ if (HDsnprintf(this_str, this_len, fmt_llong, tmp_llong) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ }
+
+ break;
+ }
+#endif
+
+ default:
+ H5_BAD_ARGUMENT_ERROR(
+ ENVONLY, "h5str_sprintf: integer datatype size didn't match any of expected sizes");
+ break;
+ }
+
+ break;
+ }
+
+ case H5T_COMPOUND: {
+ unsigned i;
+ size_t offset;
+
+ if ((n = H5Tget_nmembers(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!h5str_append(out_str, H5_COMPOUND_BEGIN_INDICATOR))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ for (i = 0; i < (unsigned)n; i++) {
+ offset = H5Tget_member_offset(tid, i);
+
+ if ((mtid = H5Tget_member_type(tid, i)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!h5str_sprintf(ENVONLY, out_str, container, mtid, &cptr[offset], expand_data))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if ((i + 1) < (unsigned)n)
+ if (!h5str_append(out_str, ", "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ if (H5Tclose(mtid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ mtid = H5I_INVALID_HID;
+ }
+
+ if (!h5str_append(out_str, H5_COMPOUND_END_INDICATOR))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ break;
+ }
+
+ case H5T_ENUM: {
+ char enum_name[1024];
+
+ if (H5Tenum_nameof(tid, cptr, enum_name, sizeof enum_name) >= 0) {
+ if (!h5str_append(out_str, enum_name))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+ else {
+ size_t i;
+
+ 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 (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 (HDsnprintf(this_str, this_len, "%s%02x", i ? ":" : "", ucptr[i]) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ }
+ }
+
+ break;
+ }
+
+ case H5T_REFERENCE: {
+ if (H5R_DSET_REG_REF_BUF_SIZE == typeSize) {
+ if (h5str_old_region_dataset(ENVONLY, out_str, container, cptr, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else if (H5R_OBJ_REF_BUF_SIZE == typeSize) {
+ H5O_info2_t oi;
+ hid_t obj = H5I_INVALID_HID;
+ char *obj_tok_str = NULL;
+
+ /*
+ * Object references -- show the type and OID of the referenced
+ * object.
+ */
+
+ if (NULL == (this_str = (char *)HDmalloc(64)))
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer");
+
+ if ((obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, cptr)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Oget_info3(obj, &oi, H5O_INFO_ALL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Print object data and close object */
+ H5Otoken_to_str(obj, &oi.token, &obj_tok_str);
+
+ switch (oi.type) {
+ case H5O_TYPE_GROUP:
+ if (HDsprintf(this_str, "%s %s", H5_TOOLS_GROUP, obj_tok_str) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure");
+ break;
+
+ case H5O_TYPE_DATASET:
+ if (HDsprintf(this_str, "%s %s", H5_TOOLS_DATASET, obj_tok_str) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure");
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ if (HDsprintf(this_str, "%s %s", H5_TOOLS_DATATYPE, obj_tok_str) < 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-%s", (unsigned)oi.type, obj_tok_str) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure");
+ break;
+ }
+
+ if (obj_tok_str) {
+ H5free_memory(obj_tok_str);
+ obj_tok_str = NULL;
+ }
+
+ if (H5Oclose(obj) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ obj = H5I_INVALID_HID;
+ }
+ else {
+ /* H5T_STD_REF */
+ hid_t new_obj_id = H5I_INVALID_HID;
+ H5O_type_t obj_type = -1; /* Object type */
+ H5R_type_t ref_type; /* Reference type */
+
+ H5R_ref_t loc_ref;
+
+ HDmemcpy(&loc_ref, cptr, sizeof(H5R_ref_t));
+
+ ref_type = H5Rget_type(&loc_ref);
+ if (!h5str_is_zero(&loc_ref, H5Tget_size(H5T_STD_REF))) {
+ switch (ref_type) {
+ case H5R_OBJECT1:
+ if (H5Rget_obj_type3(&loc_ref, H5P_DEFAULT, &obj_type) >= 0) {
+ switch (obj_type) {
+ case H5O_TYPE_DATASET:
+ if (h5str_region_dataset(ENVONLY, out_str, &loc_ref, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+
+ case H5O_TYPE_GROUP:
+ case H5O_TYPE_NAMED_DATATYPE:
+ case H5O_TYPE_MAP:
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default: {
+ /* Object references -- show the type and
+ * OID of the referenced object. */
+ H5O_info2_t oi;
+ char *obj_tok_str = NULL;
+ if ((new_obj_id =
+ H5Ropen_object(&loc_ref, H5P_DEFAULT, H5P_DEFAULT)) >= 0) {
+ H5Oget_info3(new_obj_id, &oi, H5O_INFO_BASIC);
+ H5Otoken_to_str(new_obj_id, &oi.token, &obj_tok_str);
+ if (H5Dclose(new_obj_id) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+ else
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ size_t this_len = 14;
+ if (NULL == (this_str = (char *)HDmalloc(this_len)))
+ H5_OUT_OF_MEMORY_ERROR(
+ ENVONLY, "h5str_sprintf: failed to allocate string buffer");
+ switch (oi.type) {
+ case H5O_TYPE_GROUP:
+ if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_GROUP) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY,
+ "h5str_sprintf: HDsnprintf failure");
+ break;
+
+ case H5O_TYPE_DATASET:
+ if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_DATASET) <
+ 0)
+ H5_JNI_FATAL_ERROR(ENVONLY,
+ "h5str_sprintf: HDsnprintf failure");
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ if (HDsnprintf(this_str, this_len, "%s ", H5_TOOLS_DATATYPE) <
+ 0)
+ H5_JNI_FATAL_ERROR(ENVONLY,
+ "h5str_sprintf: HDsnprintf failure");
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ if (HDsnprintf(this_str, this_len, "%u-", (unsigned)oi.type) <
+ 0)
+ H5_JNI_FATAL_ERROR(ENVONLY,
+ "h5str_sprintf: HDsnprintf failure");
+ break;
+ } /* end switch */
+ if (!h5str_append(out_str, this_str))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ HDfree(this_str);
+ this_str = NULL;
+
+ /* Print OID */
+ {
+ char *token_str;
+
+ H5Otoken_to_str(tid, &oi.token, &token_str);
+
+ size_t that_len = 64 + strlen(token_str) + 1;
+ if (NULL == (this_str = HDmalloc(that_len)))
+ H5_OUT_OF_MEMORY_ERROR(
+ ENVONLY,
+ "h5str_sprintf: failed to allocate string buffer");
+ if (HDsnprintf(this_str, that_len, "%lu:%s", oi.fileno,
+ token_str) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY,
+ "h5str_sprintf: HDsnprintf failure");
+
+ H5free_memory(token_str);
+ }
+ } break;
+ } /* end switch */
+ }
+ else
+ H5_LIBRARY_ERROR(ENVONLY);
+ break;
+ case H5R_DATASET_REGION1:
+ if (h5str_region_dataset(ENVONLY, out_str, &loc_ref, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ case H5R_OBJECT2:
+ if (H5Rget_obj_type3(&loc_ref, H5P_DEFAULT, &obj_type) >= 0) {
+ switch (obj_type) {
+ case H5O_TYPE_GROUP:
+ break;
+
+ case H5O_TYPE_DATASET:
+ if (h5str_region_dataset(ENVONLY, out_str, &loc_ref, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ break;
+
+ case H5O_TYPE_MAP:
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ break;
+ } /* end switch */
+ }
+ else
+ H5_ASSERTION_ERROR(ENVONLY, "h5str_sprintf: H5R_OBJECT2 failed");
+ break;
+ case H5R_DATASET_REGION2:
+ if (h5str_region_dataset(ENVONLY, out_str, &loc_ref, expand_data) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ case H5R_ATTR:
+ if ((new_obj_id = H5Ropen_attr(&loc_ref, H5P_DEFAULT, H5P_DEFAULT)) >= 0) {
+ if (h5str_dump_region_attribute(ENVONLY, out_str, new_obj_id) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ if (H5Aclose(new_obj_id) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+ break;
+ case H5R_BADTYPE:
+ case H5R_MAXTYPE:
+ default:
+ break;
+ } /* end switch */
+ }
+
+ if (H5Rdestroy(&loc_ref) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+
+ break;
+ }
+
+ case H5T_ARRAY: {
+ hsize_t dims[H5S_MAX_RANK], i, total_elmts;
+ size_t baseSize;
+ int rank = 0;
+
+ if (!h5str_append(out_str, H5_ARRAY_BEGIN_INDICATOR))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ if ((mtid = H5Tget_super(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!(baseSize = H5Tget_size(mtid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((rank = H5Tget_array_ndims(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Tget_array_dims2(tid, dims) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ for (i = 0, total_elmts = 1; i < (hsize_t)rank; i++)
+ total_elmts *= dims[i];
+
+ for (i = 0; i < total_elmts; i++) {
+ if (!h5str_sprintf(ENVONLY, out_str, container, mtid, &(cptr[i * baseSize]), expand_data))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if ((i + 1) < total_elmts)
+ if (!h5str_append(out_str, ", "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+
+ if (!h5str_append(out_str, H5_ARRAY_END_INDICATOR))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ if (H5Tclose(mtid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ mtid = H5I_INVALID_HID;
+
+ break;
+ }
+
+ case H5T_VLEN: {
+ unsigned int i;
+ size_t baseSize;
+ hvl_t *vl_buf = (hvl_t *)in_buf;
+
+ if ((mtid = H5Tget_super(tid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!(baseSize = H5Tget_size(mtid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!h5str_append(out_str, H5_VLEN_BEGIN_INDICATOR))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ for (i = 0; i < (unsigned)vl_buf->len; i++) {
+ if (!h5str_sprintf(ENVONLY, out_str, container, mtid, &(((char *)vl_buf->p)[i * baseSize]),
+ expand_data))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if ((i + 1) < (unsigned)vl_buf->len)
+ if (!h5str_append(out_str, ", "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+
+ if (!h5str_append(out_str, H5_VLEN_END_INDICATOR))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ if (H5Tclose(mtid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ mtid = H5I_INVALID_HID;
+
+ break;
+ }
+
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES: {
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: invalid datatype class");
+ break;
+ }
+
+ case H5T_TIME:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ default: {
+ size_t i;
+
+ /* All other types get printed as hexadecimal */
+
+ 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 (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 (HDsnprintf(this_str, this_len, "%s%02x", i ? ":" : "", ucptr[i]) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsnprintf failure");
+ }
+
+ break;
+ }
+ }
+
+ if (this_str) {
+ if (!h5str_append(out_str, this_str))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ HDfree(this_str);
+ this_str = NULL;
+ } /* end if */
+
+ retVal = HDstrlen(out_str->s);
+
+done:
+ if (mtid >= 0)
+ H5Tclose(mtid);
+
+ return retVal;
+} /* end h5str_sprintf */
+
+/*-------------------------------------------------------------------------
+ * Purpose: Print the data values from a dataset referenced by region blocks.
+ *
+ * Description:
+ * 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 SUCCEED
+ *-------------------------------------------------------------------------
+ */
+static int
+h5str_print_region_data_blocks(JNIEnv *env, hid_t region_id, h5str_t *str, int ndims, hid_t type_id,
+ hssize_t nblocks, hsize_t *ptdata)
+{
+ unsigned indx;
+ hsize_t *dims1 = NULL;
+ hsize_t *start = NULL;
+ hsize_t *count = NULL;
+ hsize_t blkndx;
+ hsize_t total_size[H5S_MAX_RANK];
+ hsize_t numelem;
+ hsize_t numindex;
+ size_t jndx;
+ size_t type_size;
+ hid_t mem_space = H5I_INVALID_HID;
+ hid_t sid1 = H5I_INVALID_HID;
+ void *region_buf = NULL;
+ int ret_value = FAIL;
+
+ if (ndims < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_print_region_data_blocks: ndims < 0");
+ if (nblocks < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_print_region_data_blocks: nblocks < 0");
+
+ /* Get the dataspace of the dataset */
+ if ((sid1 = H5Dget_space(region_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Allocate space for the dimension array */
+ if (NULL == (dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_print_region_data_blocks: failed to allocate dimension array buffer");
+
+ /* Find the dimensions of each data space from the block coordinates */
+ for (jndx = 0, numelem = 1; jndx < (size_t)ndims; jndx++) {
+ dims1[jndx] = ptdata[jndx + (size_t)ndims] - ptdata[jndx] + 1;
+ numelem = dims1[jndx] * numelem;
+ } /* end for */
+
+ /* Create dataspace for reading buffer */
+ if ((mem_space = H5Screate_simple(ndims, dims1, NULL)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!(type_size = H5Tget_size(type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (NULL == (region_buf = HDmalloc(type_size * (size_t)numelem)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate region buffer");
+
+ /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */
+ /* 1 2 n 1 2 n */
+ if (NULL == (start = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_print_region_data_blocks: failed to allocate hyperslab start buffer");
+
+ if (NULL == (count = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_print_region_data_blocks: failed to allocate hyperslab count buffer");
+
+ for (blkndx = 0; blkndx < (hsize_t)nblocks; blkndx++) {
+ for (indx = 0; indx < (unsigned)ndims; indx++) {
+ start[indx] = ptdata[indx + blkndx * (hsize_t)ndims * 2];
+ count[indx] = dims1[indx];
+ } /* end for */
+
+ if (H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ for (numindex = 0; numindex < numelem; numindex++) {
+ if (!h5str_sprintf(ENVONLY, str, region_id, type_id, ((char *)region_buf + numindex * type_size),
+ 1))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if (numindex + 1 < numelem)
+ if (!h5str_append(str, ", "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ } /* end for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, ctx.cur_elmt++) */
+ } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */
+
+ ret_value = SUCCEED;
+
+done:
+ if (count)
+ HDfree(count);
+ if (start)
+ HDfree(start);
+ if (region_buf)
+ HDfree(region_buf);
+ if (mem_space >= 0)
+ H5Sclose(mem_space);
+ if (dims1)
+ HDfree(dims1);
+ if (sid1 >= 0)
+ H5Sclose(sid1);
+
+ return ret_value;
+} /* end h5str_print_region_data_blocks */
+
+int
+h5str_dump_region_blocks(JNIEnv *env, h5str_t *str, hid_t region_space, hid_t region_id, int expand_data)
+{
+ hssize_t nblocks;
+ hsize_t alloc_size;
+ hsize_t *ptdata = NULL;
+ hid_t dtype = H5I_INVALID_HID;
+ hid_t type_id = H5I_INVALID_HID;
+ int ndims = -1;
+ int ret_value = FAIL;
+ int i;
+ char tmp_str[256];
+
+ /*
+ * This function fails if the region does not have blocks.
+ */
+ H5E_BEGIN_TRY
+ {
+ nblocks = H5Sget_select_hyper_nblocks(region_space);
+ }
+ H5E_END_TRY;
+
+ if (nblocks <= 0) {
+ ret_value = SUCCEED;
+ goto done;
+ }
+ if ((ndims = H5Sget_simple_extent_ndims(region_space)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Print block information */
+ alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]);
+ if (NULL == (ptdata = (hsize_t *)HDmalloc((size_t)alloc_size)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_region_blocks: failed to allocate region block buffer");
+
+ if (H5Sget_select_hyper_blocklist(region_space, (hsize_t)0, (hsize_t)nblocks, ptdata) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (expand_data) {
+ if ((dtype = H5Dget_type(region_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (h5str_print_region_data_blocks(ENVONLY, region_id, str, ndims, type_id, nblocks, ptdata) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else {
+ if (!h5str_append(str, " REGION_TYPE BLOCK"))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ if (!h5str_append(str, " {"))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ for (i = 0; i < nblocks; i++) {
+ int j;
+
+ if (!h5str_append(str, " "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ /* Start coordinates and opposite corner */
+ for (j = 0; j < ndims; j++) {
+ tmp_str[0] = '\0';
+
+ 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.");
+ }
+
+ for (j = 0; j < ndims; j++) {
+ tmp_str[0] = '\0';
+
+ 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.");
+ }
+
+ if (!h5str_append(str, ") "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ tmp_str[0] = '\0';
+ }
+
+ if (!h5str_append(str, " }"))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+ ret_value = SUCCEED;
+
+done:
+ if (type_id >= 0)
+ H5Tclose(type_id);
+ if (dtype >= 0)
+ H5Tclose(dtype);
+ if (ptdata)
+ HDfree(ptdata);
+
+ return ret_value;
+} /* end h5str_dump_region_blocks */
+
+/*-------------------------------------------------------------------------
+ * Purpose: Print the data values from a dataset referenced by region points.
+ *
+ * Description:
+ * This is a special case subfunction to print the data in a region reference of type points.
+ *
+ * Return:
+ * The function returns FAIL on error, otherwise SUCCEED
+ *-------------------------------------------------------------------------
+ */
+static int
+h5str_print_region_data_points(JNIEnv *env, hid_t region_space, hid_t region_id, h5str_t *str, int ndims,
+ hid_t type_id, hssize_t npoints, hsize_t *ptdata)
+{
+ hsize_t *dims1 = NULL;
+ hsize_t total_size[H5S_MAX_RANK];
+ size_t jndx;
+ size_t type_size;
+ hid_t mem_space = H5I_INVALID_HID;
+ void *region_buf = NULL;
+ int ret_value = FAIL;
+
+ UNUSED(ptdata);
+
+ if (npoints < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_print_region_data_points: npoints < 0");
+
+ /* Allocate space for the dimension array */
+ if (NULL == (dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_print_region_data_points: failed to allocate dimension array buffer");
+
+ dims1[0] = (hsize_t)npoints;
+
+ /* Create dataspace for reading buffer */
+ if ((mem_space = H5Screate_simple(1, dims1, NULL)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!(type_size = H5Tget_size(type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (NULL == (region_buf = HDmalloc(type_size * (size_t)npoints)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_print_region_data_points: failed to allocate region buffer");
+
+ if (H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ for (jndx = 0; jndx < (size_t)npoints; jndx++) {
+ if (H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (!h5str_sprintf(ENVONLY, str, region_id, type_id, ((char *)region_buf + jndx * type_size), 1))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if (jndx + 1 < (size_t)npoints)
+ if (!h5str_append(str, ", "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ } /* end for (jndx = 0; jndx < npoints; jndx++, elmtno++) */
+
+ ret_value = SUCCEED;
+
+done:
+ if (region_buf)
+ HDfree(region_buf);
+ if (mem_space >= 0)
+ H5Sclose(mem_space);
+ if (dims1)
+ HDfree(dims1);
+
+ return ret_value;
+} /* end h5str_print_region_data_points */
+
+int
+h5str_dump_region_points(JNIEnv *env, h5str_t *str, hid_t region_space, hid_t region_id, int expand_data)
+{
+ hsize_t alloc_size;
+ hssize_t npoints = -1;
+ hsize_t *ptdata = NULL;
+ hid_t dtype = H5I_INVALID_HID;
+ hid_t type_id = H5I_INVALID_HID;
+ int ndims = -1;
+ int ret_value = FAIL;
+ int i;
+ char tmp_str[256];
+
+ /*
+ * This function fails if the region does not have points.
+ */
+ H5E_BEGIN_TRY
+ {
+ npoints = H5Sget_select_elem_npoints(region_space);
+ }
+ H5E_END_TRY;
+
+ if (npoints <= 0) {
+ ret_value = SUCCEED;
+ goto done;
+ }
+ if ((ndims = H5Sget_simple_extent_ndims(region_space)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Print point information */
+ alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]);
+ if (NULL == (ptdata = (hsize_t *)HDmalloc((size_t)alloc_size)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "h5str_dump_region_points: failed to allocate region point data buffer");
+
+ if (H5Sget_select_elem_pointlist(region_space, (hsize_t)0, (hsize_t)npoints, ptdata) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (expand_data) {
+ if ((dtype = H5Dget_type(region_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (h5str_print_region_data_points(ENVONLY, region_space, region_id, str, ndims, type_id, npoints,
+ ptdata) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else {
+ if (!h5str_append(str, " REGION_TYPE POINT"))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ if (!h5str_append(str, " {"))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ for (i = 0; i < npoints; i++) {
+ int j;
+
+ if (!h5str_append(str, " "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+
+ for (j = 0; j < ndims; j++) {
+ tmp_str[0] = '\0';
+
+ 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.");
+ } /* end for (j = 0; j < ndims; j++) */
+
+ if (!h5str_append(str, ") "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ } /* end for (i = 0; i < npoints; i++) */
+
+ if (!h5str_append(str, " }"))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+ ret_value = SUCCEED;
+
+done:
+ if (type_id >= 0)
+ H5Tclose(type_id);
+ if (dtype >= 0)
+ H5Tclose(dtype);
+ if (ptdata)
+ HDfree(ptdata);
+
+ return ret_value;
+} /* end h5str_dump_region_points */
+
+static int
+h5str_is_zero(const void *_mem, size_t size)
+{
+ const unsigned char *mem = (const unsigned char *)_mem;
+
+ while (size-- > 0)
+ if (mem[size])
+ return 0;
+
+ return 1;
+} /* end h5str_is_zero */
+
+/*-------------------------------------------------------------------------
+ * Function: h5str_detect_vlen
+ *
+ * Purpose: Recursive check for any variable length data in given type.
+ *
+ * Return:
+ * 1 : type contains any variable length data
+ * 0 : type doesn't contain any variable length data
+ * Negative value: error occurred
+ *-------------------------------------------------------------------------
+ */
+htri_t
+h5str_detect_vlen(hid_t tid)
+{
+ htri_t ret = FAIL;
+
+ /* Recursively detect any vlen data values in type (compound, array ...) */
+ ret = H5Tdetect_class(tid, H5T_VLEN);
+ if ((ret == 1) || (ret < 0))
+ goto done;
+
+ /* Recursively detect any vlen string in type (compound, array ...) */
+ ret = h5str_detect_vlen_str(tid);
+ if ((ret == 1) || (ret < 0))
+ goto done;
+
+done:
+ return ret;
+} /* end h5str_detect_vlen */
+
+/*-------------------------------------------------------------------------
+ * Function: h5str_detect_vlen_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: error occur
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+h5str_detect_vlen_str(hid_t tid)
+{
+ H5T_class_t tclass = H5T_NO_CLASS;
+ htri_t ret = 0;
+
+ ret = H5Tis_variable_str(tid);
+ if ((ret == 1) || (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;
+ } /* end if */
+ ret = h5str_detect_vlen_str(btid);
+ if ((ret == 1) || (ret < 0)) {
+ H5Tclose(btid);
+ goto done;
+ } /* end if */
+ } /* end if */
+ else if (tclass == H5T_COMPOUND) {
+ unsigned i = 0;
+ int n = H5Tget_nmembers(tid);
+
+ if (n < 0)
+ goto done;
+
+ for (i = 0; i < (unsigned)n; i++) {
+ hid_t mtid = H5Tget_member_type(tid, i);
+
+ ret = h5str_detect_vlen_str(mtid);
+ if ((ret == 1) || (ret < 0)) {
+ H5Tclose(mtid);
+ goto done;
+ }
+ H5Tclose(mtid);
+ } /* end for */
+ } /* end else */
+
+done:
+ return ret;
+} /* end h5str_detect_vlen_str */
+
+/*-------------------------------------------------------------------------
+ * Function: h5str_get_native_type
+ *
+ * Purpose: Wrapper around H5Tget_native_type() to work around
+ * Problems with bitfields.
+ *
+ * Return: Success: datatype ID
+ * Failure: FAIL
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+h5str_get_native_type(hid_t type)
+{
+ H5T_class_t type_class;
+ hid_t p_type = H5I_INVALID_HID;
+
+ if ((type_class = H5Tget_class(type)) < 0)
+ goto done;
+
+ if (type_class == H5T_BITFIELD)
+ p_type = H5Tcopy(type);
+ else
+ p_type = H5Tget_native_type(type, H5T_DIR_DEFAULT);
+
+done:
+ return (p_type);
+} /* end h5str_get_native_type */
+
+/*-------------------------------------------------------------------------
+ * Function: h5str_get_little_endian_type
+ *
+ * Purpose: Get a little endian type from a file type
+ *
+ * Return: Success: datatype ID
+ * Failure: FAIL
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+h5str_get_little_endian_type(hid_t tid)
+{
+ H5T_class_t type_class;
+ H5T_sign_t sign;
+ size_t size;
+ hid_t p_type = H5I_INVALID_HID;
+
+ if ((type_class = H5Tget_class(tid)) < 0)
+ goto done;
+
+ if (!(size = H5Tget_size(tid)))
+ goto done;
+
+ if ((sign = H5Tget_sign(tid)) < 0)
+ goto done;
+
+ switch (type_class) {
+ case H5T_INTEGER: {
+ if (size == 1 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I8LE);
+ else if (size == 2 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I16LE);
+ else if (size == 4 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I32LE);
+ else if (size == 8 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I64LE);
+ else if (size == 1 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U8LE);
+ else if (size == 2 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U16LE);
+ else if (size == 4 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U32LE);
+ else if (size == 8 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U64LE);
+
+ break;
+ }
+
+ case H5T_FLOAT: {
+ if (size == 4)
+ p_type = H5Tcopy(H5T_IEEE_F32LE);
+ else if (size == 8)
+ p_type = H5Tcopy(H5T_IEEE_F64LE);
+
+ break;
+ }
+
+ case H5T_BITFIELD: {
+ if (size == 1)
+ p_type = H5Tcopy(H5T_STD_B8LE);
+ else if (size == 2)
+ p_type = H5Tcopy(H5T_STD_B16LE);
+ else if (size == 4)
+ p_type = H5Tcopy(H5T_STD_B32LE);
+ else if (size == 8)
+ p_type = H5Tcopy(H5T_STD_B64LE);
+
+ break;
+ }
+
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES: {
+ goto done;
+ break;
+ }
+
+ case H5T_TIME:
+ case H5T_OPAQUE:
+ case H5T_STRING:
+ case H5T_COMPOUND:
+ case H5T_REFERENCE:
+ case H5T_ENUM:
+ case H5T_VLEN:
+ case H5T_ARRAY:
+ break;
+
+ default:
+ break;
+ }
+
+done:
+ return (p_type);
+} /* end h5str_get_little_endian_type */
+
+/*-------------------------------------------------------------------------
+ * Function: h5str_get_big_endian_type
+ *
+ * Purpose: Get a big endian type from a file type
+ *
+ * Return: Success: datatype ID
+ * Failure: FAIL
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+h5str_get_big_endian_type(hid_t tid)
+{
+ H5T_class_t type_class;
+ H5T_sign_t sign;
+ size_t size;
+ hid_t p_type = H5I_INVALID_HID;
+
+ if ((type_class = H5Tget_class(tid)) < 0)
+ goto done;
+
+ if (!(size = H5Tget_size(tid)))
+ goto done;
+
+ if ((sign = H5Tget_sign(tid)) < 0)
+ goto done;
+
+ switch (type_class) {
+ case H5T_INTEGER: {
+ if (size == 1 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I8BE);
+ else if (size == 2 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I16BE);
+ else if (size == 4 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I32BE);
+ else if (size == 8 && sign == H5T_SGN_2)
+ p_type = H5Tcopy(H5T_STD_I64BE);
+ else if (size == 1 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U8BE);
+ else if (size == 2 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U16BE);
+ else if (size == 4 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U32BE);
+ else if (size == 8 && sign == H5T_SGN_NONE)
+ p_type = H5Tcopy(H5T_STD_U64BE);
+
+ break;
+ }
+
+ case H5T_FLOAT: {
+ if (size == 4)
+ p_type = H5Tcopy(H5T_IEEE_F32BE);
+ else if (size == 8)
+ p_type = H5Tcopy(H5T_IEEE_F64BE);
+
+ break;
+ }
+
+ case H5T_BITFIELD: {
+ if (size == 1)
+ p_type = H5Tcopy(H5T_STD_B8BE);
+ else if (size == 2)
+ p_type = H5Tcopy(H5T_STD_B16BE);
+ else if (size == 4)
+ p_type = H5Tcopy(H5T_STD_B32BE);
+ else if (size == 8)
+ p_type = H5Tcopy(H5T_STD_B64BE);
+
+ break;
+ }
+
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES: {
+ goto done;
+ break;
+ }
+
+ case H5T_TIME:
+ case H5T_OPAQUE:
+ case H5T_STRING:
+ case H5T_COMPOUND:
+ case H5T_REFERENCE:
+ case H5T_ENUM:
+ case H5T_VLEN:
+ case H5T_ARRAY:
+ break;
+
+ default:
+ break;
+ }
+
+done:
+ return (p_type);
+} /* end h5str_get_big_endian_type */
+
+/*-------------------------------------------------------------------------
+ * Function: render_bin_output
+ *
+ * Purpose: Write one element of memory buffer to a binary file stream
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *-------------------------------------------------------------------------
+ */
+static int
+h5str_render_bin_output(FILE *stream, hid_t container, hid_t tid, void *_mem, hsize_t block_nelmts)
+{
+ unsigned char *mem = (unsigned char *)_mem;
+ H5T_class_t type_class;
+ hsize_t block_index;
+ size_t size; /* datum size */
+ int ret_value = 0;
+
+ if (!(size = H5Tget_size(tid))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if ((type_class = H5Tget_class(tid)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ switch (type_class) {
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_ENUM: {
+ block_index = block_nelmts * size;
+ while (block_index > 0) {
+ size_t bytes_in = 0; /* # of bytes to write */
+ size_t bytes_wrote = 0; /* # of bytes written */
+
+ if (block_index > sizeof(size_t))
+ bytes_in = sizeof(size_t);
+ else
+ bytes_in = (size_t)block_index;
+
+ bytes_wrote = fwrite(mem, 1, bytes_in, stream);
+
+ if (bytes_wrote != bytes_in || (0 == bytes_wrote && ferror(stream))) {
+ ret_value = FAIL;
+ break;
+ }
+
+ block_index -= (hsize_t)bytes_wrote;
+ mem = mem + bytes_wrote;
+ }
+
+ break;
+ }
+
+ case H5T_STRING: {
+ unsigned int i;
+ H5T_str_t pad;
+ char *s = NULL;
+ unsigned char tempuchar;
+
+ if ((pad = H5Tget_strpad(tid)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ for (block_index = 0; block_index < block_nelmts; block_index++) {
+ mem = ((unsigned char *)_mem) + block_index * size;
+
+ if (H5Tis_variable_str(tid)) {
+ s = *(char **)((void *)mem);
+ if (s != NULL)
+ size = HDstrlen(s);
+ }
+ else {
+ s = (char *)mem;
+ }
+ for (i = 0; i < size && (s[i] || pad != H5T_STR_NULLTERM); i++) {
+ HDmemcpy(&tempuchar, &s[i], sizeof(unsigned char));
+ if (1 != fwrite(&tempuchar, sizeof(unsigned char), 1, stream)) {
+ ret_value = FAIL;
+ break;
+ }
+ } /* i */
+ if (ret_value < 0)
+ break;
+ } /* for (block_index = 0; block_index < block_nelmts; block_index++) */
+
+ break;
+ }
+
+ case H5T_COMPOUND: {
+ unsigned j;
+ size_t offset;
+ hid_t memb = H5I_INVALID_HID;
+ int nmembs;
+
+ if ((nmembs = H5Tget_nmembers(tid)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ for (block_index = 0; block_index < block_nelmts; block_index++) {
+ mem = ((unsigned char *)_mem) + block_index * size;
+ for (j = 0; j < (unsigned)nmembs; j++) {
+ offset = H5Tget_member_offset(tid, j);
+ memb = H5Tget_member_type(tid, j);
+
+ if (h5str_render_bin_output(stream, container, memb, mem + offset, 1) < 0) {
+ H5Tclose(memb);
+ ret_value = FAIL;
+ break;
+ }
+
+ H5Tclose(memb);
+ }
+
+ if (ret_value < 0)
+ break;
+ }
+
+ break;
+ }
+
+ case H5T_ARRAY: {
+ hsize_t dims[H5S_MAX_RANK], temp_nelmts, nelmts;
+ hid_t memb;
+ int k, ndims;
+
+ /* Get the array's base datatype for each element */
+ if ((memb = H5Tget_super(tid)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if ((ndims = H5Tget_array_ndims(tid)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (H5Tget_array_dims2(tid, dims) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Calculate the number of array elements */
+ for (k = 0, nelmts = 1; k < ndims; k++) {
+ temp_nelmts = nelmts;
+ temp_nelmts *= dims[k];
+ nelmts = (size_t)temp_nelmts;
+ }
+
+ for (block_index = 0; block_index < block_nelmts; block_index++) {
+ mem = ((unsigned char *)_mem) + block_index * size;
+
+ /* dump the array element */
+ if (h5str_render_bin_output(stream, container, memb, mem, nelmts) < 0) {
+ ret_value = FAIL;
+ break;
+ }
+ }
+
+ H5Tclose(memb);
+
+ break;
+ }
+
+ case H5T_VLEN: {
+ hsize_t nelmts;
+ hid_t memb;
+
+ /* Get the VL sequences's base datatype for each element */
+ if ((memb = H5Tget_super(tid)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ for (block_index = 0; block_index < block_nelmts; block_index++) {
+ hvl_t vl_elem;
+
+ HDmemcpy(&vl_elem, ((unsigned char *)_mem) + block_index * size, sizeof(hvl_t));
+
+ /* Get the number of sequence elements */
+ nelmts = vl_elem.len;
+
+ /* dump the array element */
+ if (h5str_render_bin_output(stream, container, memb, ((char *)(vl_elem.p)), nelmts) < 0) {
+ ret_value = FAIL;
+ break;
+ }
+ }
+
+ H5Tclose(memb);
+
+ break;
+ }
+
+ case H5T_REFERENCE: {
+ hid_t region_id = H5I_INVALID_HID;
+ hid_t region_space = H5I_INVALID_HID;
+ H5S_sel_type region_type;
+
+ /* Region data */
+ for (block_index = 0; block_index < block_nelmts; block_index++) {
+ H5R_ref_t loc_ref;
+
+ HDmemcpy(&loc_ref, ((unsigned char *)_mem) + block_index * size, sizeof(H5R_ref_t));
+
+ if ((region_id = H5Ropen_object(&loc_ref, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ continue;
+ if ((region_space = H5Ropen_region(&loc_ref, H5P_DEFAULT, H5P_DEFAULT)) >= 0) {
+ if (!h5str_is_zero(&loc_ref, H5Tget_size(H5T_STD_REF))) {
+ region_type = H5Sget_select_type(region_space);
+ if (region_type == H5S_SEL_POINTS)
+ ret_value =
+ render_bin_output_region_points(stream, region_space, region_id, container);
+ else if (region_type == H5S_SEL_HYPERSLABS)
+ ret_value =
+ render_bin_output_region_blocks(stream, region_space, region_id, container);
+ }
+ H5Sclose(region_space);
+ } /* end if (region_space >= 0) */
+ H5Dclose(region_id);
+
+ if (ret_value < 0)
+ break;
+ }
+
+ break;
+ }
+
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES: {
+ ret_value = FAIL;
+ goto done;
+ break;
+ }
+
+ case H5T_TIME:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ default:
+ for (block_index = 0; block_index < block_nelmts; block_index++) {
+ mem = ((unsigned char *)_mem) + block_index * size;
+ if (size != fwrite(mem, sizeof(char), size, stream)) {
+ ret_value = FAIL;
+ break;
+ }
+ }
+ break;
+ }
+
+done:
+ return ret_value;
+} /* end h5str_render_bin_output */
+
+/*-------------------------------------------------------------------------
+ * Purpose: Print the data values from a dataset referenced by region blocks.
+ *
+ * Description:
+ * 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 SUCCEED
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+render_bin_output_region_data_blocks(FILE *stream, hid_t region_id, hid_t container, int ndims, hid_t type_id,
+ hssize_t nblocks, hsize_t *ptdata)
+{
+ hsize_t *dims1 = NULL;
+ hsize_t *start = NULL;
+ hsize_t *count = NULL;
+ hsize_t numelem;
+ hsize_t total_size[H5S_MAX_RANK];
+ size_t type_size;
+ hid_t sid1 = H5I_INVALID_HID;
+ hid_t mem_space = H5I_INVALID_HID;
+ void *region_buf = NULL;
+ int blkndx;
+ int jndx;
+ int ret_value = SUCCEED;
+
+ /* Get the dataspace of the dataset */
+ if ((sid1 = H5Dget_space(region_id)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Allocate space for the dimension array */
+ if (NULL == (dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Find the dimensions of each data space from the block coordinates */
+ for (jndx = 0, numelem = 1; jndx < ndims; jndx++) {
+ dims1[jndx] = ptdata[jndx + ndims] - ptdata[jndx] + 1;
+ numelem = dims1[jndx] * numelem;
+ }
+
+ /* Create dataspace for reading buffer */
+ if ((mem_space = H5Screate_simple(ndims, dims1, NULL)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (!(type_size = H5Tget_size(type_id))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (NULL == (region_buf = HDmalloc(type_size * (size_t)numelem))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */
+ /* 1 2 n 1 2 n */
+ if (NULL == (start = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (NULL == (count = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ for (blkndx = 0; blkndx < nblocks; blkndx++) {
+ for (jndx = 0; jndx < ndims; jndx++) {
+ start[jndx] = ptdata[jndx + blkndx * ndims * 2];
+ count[jndx] = dims1[jndx];
+ }
+
+ if (H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (h5str_render_bin_output(stream, container, type_id, (char *)region_buf, numelem) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Render the region data element end */
+ } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */
+
+done:
+ if (count)
+ HDfree(count);
+ if (start)
+ HDfree(start);
+ if (region_buf)
+ HDfree(region_buf);
+ if (mem_space >= 0)
+ H5Sclose(mem_space);
+ if (dims1)
+ HDfree(dims1);
+ if (sid1 >= 0)
+ H5Sclose(sid1);
+
+ return ret_value;
+} /* end render_bin_output_region_data_blocks */
+
+/*-------------------------------------------------------------------------
+ * Purpose: Print some values from a dataset referenced by region blocks.
+ *
+ * Description:
+ * This is a special case subfunction to dump a region reference using blocks.
+ *
+ * Return:
+ * The function returns False if ERROR, otherwise True
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+render_bin_output_region_blocks(FILE *stream, hid_t region_space, hid_t region_id, hid_t container)
+{
+ hssize_t nblocks;
+ hsize_t alloc_size;
+ hsize_t *ptdata = NULL;
+ hid_t dtype = H5I_INVALID_HID;
+ hid_t type_id = H5I_INVALID_HID;
+ int ndims;
+ int ret_value = SUCCEED;
+
+ if ((nblocks = H5Sget_select_hyper_nblocks(region_space)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (nblocks > 0) {
+ /* Print block information */
+ if ((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]);
+
+ if (NULL == (ptdata = (hsize_t *)HDmalloc((size_t)alloc_size))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (H5Sget_select_hyper_blocklist(region_space, (hsize_t)0, (hsize_t)nblocks, ptdata) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if ((dtype = H5Dget_type(region_id)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (render_bin_output_region_data_blocks(stream, region_id, container, ndims, type_id, nblocks,
+ ptdata) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+ }
+
+done:
+ if (type_id >= 0)
+ H5Tclose(type_id);
+ if (dtype >= 0)
+ H5Tclose(dtype);
+ if (ptdata)
+ HDfree(ptdata);
+
+ return ret_value;
+} /* end render_bin_output_region_blocks */
+
+/*-------------------------------------------------------------------------
+ * Purpose: Print the data values from a dataset referenced by region points.
+ *
+ * Description:
+ * This is a special case subfunction to print the data in a region reference of type points.
+ *
+ * Return:
+ * The function returns FAIL on error, otherwise SUCCEED
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+render_bin_output_region_data_points(FILE *stream, hid_t region_space, hid_t region_id, hid_t container,
+ int ndims, hid_t type_id, hssize_t npoints, hsize_t *ptdata)
+{
+ hsize_t *dims1 = NULL;
+ size_t type_size;
+ hid_t mem_space = H5I_INVALID_HID;
+ void *region_buf = NULL;
+ int ret_value = SUCCEED;
+
+ UNUSED(ptdata);
+
+ if (!(type_size = H5Tget_size(type_id))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (NULL == (region_buf = HDmalloc(type_size * (size_t)npoints))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Allocate space for the dimension array */
+ if (NULL == (dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ dims1[0] = (hsize_t)npoints;
+
+ if ((mem_space = H5Screate_simple(1, dims1, NULL)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (H5Sget_simple_extent_dims(region_space, dims1, NULL) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (h5str_render_bin_output(stream, container, type_id, (char *)region_buf, (hsize_t)npoints) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+done:
+ if (dims1)
+ HDfree(dims1);
+ if (mem_space >= 0)
+ H5Sclose(mem_space);
+ if (region_buf)
+ HDfree(region_buf);
+
+ return ret_value;
+} /* end render_bin_output_region_data_points */
+
+/*-------------------------------------------------------------------------
+ * Purpose: Print some values from a dataset referenced by region points.
+ *
+ * Description:
+ * This is a special case subfunction to dump a region reference using points.
+ *
+ * Return:
+ * The function returns False if the last dimension has been reached, otherwise True
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+render_bin_output_region_points(FILE *stream, hid_t region_space, hid_t region_id, hid_t container)
+{
+ hssize_t npoints;
+ hsize_t alloc_size;
+ hsize_t *ptdata = NULL;
+ hid_t dtype = H5I_INVALID_HID;
+ hid_t type_id = H5I_INVALID_HID;
+ int ndims;
+ int ret_value = SUCCEED;
+
+ if ((npoints = H5Sget_select_elem_npoints(region_space)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (npoints > 0) {
+ /* Allocate space for the dimension array */
+ if ((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]);
+
+ if (NULL == (ptdata = (hsize_t *)HDmalloc((size_t)alloc_size))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (H5Sget_select_elem_pointlist(region_space, (hsize_t)0, (hsize_t)npoints, ptdata) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if ((dtype = H5Dget_type(region_id)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if (render_bin_output_region_data_points(stream, region_space, region_id, container, ndims, type_id,
+ npoints, ptdata) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+ }
+
+done:
+ if (type_id >= 0)
+ H5Tclose(type_id);
+ if (dtype >= 0)
+ H5Tclose(dtype);
+ if (ptdata)
+ HDfree(ptdata);
+
+ return ret_value;
+} /* end render_bin_output_region_points */
+
+/*-------------------------------------------------------------------------
+ * Purpose: Print some values from an attribute referenced by object reference.
+ *
+ * Parameters Description:
+ * FILE *buffer is the string into which to render
+ *-------------------------------------------------------------------------
+ */
+static int
+h5str_dump_region_attribute(JNIEnv *env, h5str_t *str, hid_t region_id)
+{
+ int ret_value = SUCCEED;
+ hid_t atype = H5I_INVALID_HID;
+ hid_t type_id = H5I_INVALID_HID;
+ hid_t region_space = H5I_INVALID_HID;
+ hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/
+ size_t i; /* counter */
+ size_t size; /* datum size */
+ int sndims; /* rank of dataspace */
+ hsize_t p_nelmts; /* total selected elmts */
+ hsize_t alloc_size;
+
+ unsigned char *buf = NULL; /* buffer for raw data */
+
+ /* VL data special information */
+ unsigned int vl_data = 0; /* contains VL datatypes */
+
+ if ((region_space = H5Aget_space(region_id)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if ((sndims = H5Sget_simple_extent_ndims(region_space)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Assume entire data space to be read */
+ H5Sget_simple_extent_dims(region_space, total_size, NULL);
+ p_nelmts = 1;
+
+ for (i = 0; i < (size_t)sndims; i++)
+ p_nelmts *= total_size[i];
+
+ if ((atype = H5Aget_type(region_id)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+ if ((type_id = H5Tget_native_type(atype, H5T_DIR_DEFAULT)) < 0) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* Check if we have VL data in the dataset's datatype */
+ if (h5str_detect_vlen(type_id) == TRUE)
+ vl_data = TRUE;
+
+ if (!(size = H5Tget_size(type_id))) {
+ ret_value = FAIL;
+ goto done;
+ }
+
+ alloc_size = p_nelmts * size;
+ HDassert(alloc_size == (hsize_t)((size_t)alloc_size)); /*check for overflow*/
+ if (NULL != (buf = (unsigned char *)HDmalloc((size_t)alloc_size))) {
+ /* Read the data */
+ if (H5Aread(region_id, type_id, buf) >= 0) {
+
+ for (i = 0; i < p_nelmts; i++) {
+ size_t bytes_in = 0; /* # of bytes to write */
+ void *memref = buf + i * size;
+
+ if (!(bytes_in = h5str_sprintf(ENVONLY, str, region_id, type_id, memref, 1)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if ((i < p_nelmts - 1) && (bytes_in > 0)) {
+ if (!h5str_append(str, ", "))
+ H5_ASSERTION_ERROR(ENVONLY, "Unable to append string.");
+ }
+ }
+
+ /* Reclaim any VL memory, if necessary */
+ if (vl_data) {
+ if (H5Treclaim(type_id, region_space, H5P_DEFAULT, buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+ }
+ else
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+
+done:
+ if (buf)
+ HDfree(buf);
+ if (region_space >= 0)
+ H5Sclose(region_space);
+ if (type_id >= 0)
+ H5Tclose(type_id);
+ if (atype >= 0)
+ H5Tclose(type_id);
+
+ return ret_value;
+}
+
+int
+h5str_dump_simple_dset(JNIEnv *env, FILE *stream, hid_t dset, int binary_order)
+{
+ hid_t f_space = H5I_INVALID_HID; /* file data space */
+ hsize_t elmtno; /* counter */
+ size_t i = 0; /* counter */
+ int sndims; /* rank of dataspace */
+ int carry; /* counter carry value */
+ hsize_t zero[8]; /* vector of zeros */
+ hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/
+
+ /* Stripmine info */
+ hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */
+ hsize_t sm_nbytes; /* bytes per stripmine */
+ hsize_t sm_nelmts; /* elements per stripmine */
+ unsigned char *sm_buf = NULL; /* buffer for raw data */
+ hid_t sm_space = H5I_INVALID_HID; /* stripmine data space */
+
+ /* Hyperslab info */
+ hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */
+ hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */
+ hsize_t hs_nelmts; /* elements in request */
+
+ /* VL data special information */
+ unsigned int vl_data = 0; /* contains VL datatypes */
+ int ret_value = FAIL;
+
+ hid_t p_type = H5I_INVALID_HID;
+ hid_t f_type = H5I_INVALID_HID;
+
+ if (dset < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_dump_simple_dset: dset ID < 0");
+
+ if ((f_type = H5Dget_type(dset)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((f_space = H5Dget_space(dset)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((sndims = H5Sget_simple_extent_ndims(f_space)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Assume entire data space to be printed */
+ if (H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Tequal(f_type, H5T_STD_REF_DSETREG)) {
+ hssize_t p_nelmts; /* total selected elmts */
+
+ if ((p_nelmts = H5Sget_simple_extent_npoints(f_space)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (NULL ==
+ (sm_buf = (unsigned char *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), (size_t)p_nelmts)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_mem: failed to allocate sm_buf");
+
+ /* Read the data */
+ if (H5Dread(dset, H5T_STD_REF, H5S_ALL, H5S_ALL, H5P_DEFAULT, sm_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (binary_order == 99) {
+ if (h5str_dump_simple_data(ENVONLY, stream, dset, H5T_STD_REF, sm_buf, (size_t)p_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else {
+ if (h5str_render_bin_output(stream, dset, H5T_STD_REF, sm_buf, (size_t)p_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ }
+ else {
+ /* Print info */
+ size_t p_type_nbytes; /* size of memory type */
+ hsize_t p_nelmts; /* total selected elmts */
+
+ switch (binary_order) {
+ case 1: {
+ if ((p_type = h5str_get_native_type(f_type)) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ break;
+ }
+
+ case 2: {
+ if ((p_type = h5str_get_little_endian_type(f_type)) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ break;
+ }
+
+ case 3: {
+ if ((p_type = h5str_get_big_endian_type(f_type)) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ break;
+ }
+
+ default: {
+ if ((p_type = H5Tcopy(f_type)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ break;
+ }
+ }
+
+ /* Calculate the number of elements we're going to print */
+ p_nelmts = 1;
+
+ if (sndims > 0) {
+ for (i = 0; i < (size_t)sndims; i++)
+ p_nelmts *= total_size[i];
+ } /* end if */
+
+ if (p_nelmts > 0) {
+ /* Check if we have VL data in the dataset's datatype */
+ if (h5str_detect_vlen(p_type) != 0)
+ vl_data = 1;
+
+ /*
+ * Determine the strip mine size and allocate a buffer. The strip mine is
+ * a hyperslab whose size is manageable.
+ */
+ if (!(sm_nbytes = p_type_nbytes = H5Tget_size(p_type)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (sndims > 0) {
+ for (i = (size_t)sndims; i > 0; --i) {
+ hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes;
+ if (size == 0) /* datum size > H5TOOLS_BUFSIZE */
+ size = 1;
+ sm_size[i - 1] = (((total_size[i - 1]) < (size)) ? (total_size[i - 1]) : (size));
+ sm_nbytes *= sm_size[i - 1];
+ }
+ }
+
+ if (sm_nbytes > 0) {
+ if (NULL == (sm_buf = (unsigned char *)HDmalloc((size_t)sm_nbytes)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_dset: failed to allocate sm_buf");
+
+ sm_nelmts = sm_nbytes / p_type_nbytes;
+
+ if ((sm_space = H5Screate_simple(1, &sm_nelmts, NULL)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* The stripmine loop */
+ HDmemset(hs_offset, 0, sizeof hs_offset);
+ HDmemset(zero, 0, sizeof zero);
+
+ for (elmtno = 0; elmtno < (hsize_t)p_nelmts; elmtno += hs_nelmts) {
+ /* Calculate the hyperslab size */
+ if (sndims > 0) {
+ for (i = 0, hs_nelmts = 1; i < (size_t)sndims; i++) {
+ hs_size[i] = (((total_size[i] - hs_offset[i]) < (sm_size[i]))
+ ? (total_size[i] - hs_offset[i])
+ : (sm_size[i]));
+ hs_nelmts *= hs_size[i];
+ }
+
+ if (H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+ else {
+ if (H5Sselect_all(f_space) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Sselect_all(sm_space) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ hs_nelmts = 1;
+ }
+
+ /* Read the data */
+ if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (binary_order == 99) {
+ if (h5str_dump_simple_data(ENVONLY, stream, dset, p_type, sm_buf, hs_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else {
+ if (h5str_render_bin_output(stream, dset, p_type, sm_buf, hs_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+
+ /* Reclaim any VL memory, if necessary */
+ if (vl_data) {
+ if (H5Treclaim(p_type, sm_space, H5P_DEFAULT, sm_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+
+ /* Calculate the next hyperslab offset */
+ for (i = (size_t)sndims, carry = 1; i > 0 && carry; --i) {
+ hs_offset[i - 1] += hs_size[i - 1];
+
+ if (hs_offset[i - 1] == total_size[i - 1])
+ hs_offset[i - 1] = 0;
+ else
+ carry = 0;
+ }
+ }
+ }
+ }
+ }
+
+ ret_value = SUCCEED;
+
+done:
+ if (sm_space >= 0)
+ H5Sclose(sm_space);
+ if (sm_buf)
+ HDfree(sm_buf);
+ if (f_space >= 0)
+ H5Sclose(f_space);
+ if (p_type >= 0)
+ H5Tclose(p_type);
+ if (f_type >= 0)
+ H5Tclose(f_type);
+
+ return ret_value;
+} /* end h5str_dump_simple_dset */
+
+int
+h5str_dump_simple_mem(JNIEnv *env, FILE *stream, hid_t attr_id, int binary_order)
+{
+ hid_t f_space = H5I_INVALID_HID; /* file data space */
+ hsize_t alloc_size;
+ int sndims; /* rank of dataspace */
+ unsigned i; /* counters */
+ hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset */
+ int ret_value = 0;
+
+ unsigned char *sm_buf = NULL; /* buffer for raw data */
+
+ /* VL data special information */
+ unsigned int vl_data = 0; /* contains VL datatypes */
+ hid_t p_type = H5I_INVALID_HID;
+ hid_t f_type = H5I_INVALID_HID;
+
+ if (attr_id < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_dump_simple_mem: attr ID < 0");
+
+ if ((f_type = H5Aget_type(attr_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5I_INVALID_HID == (f_space = H5Aget_space(attr_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((sndims = H5Sget_simple_extent_ndims(f_space)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Tequal(f_type, H5T_STD_REF_DSETREG)) {
+ hssize_t p_nelmts; /* total selected elmts */
+
+ if ((p_nelmts = H5Sget_simple_extent_npoints(f_space)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (NULL ==
+ (sm_buf = (unsigned char *)HDcalloc(MAX(sizeof(unsigned), sizeof(H5R_ref_t)), (size_t)p_nelmts)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_mem: failed to allocate sm_buf");
+
+ /* Read the data */
+ if (H5Aread(attr_id, H5T_STD_REF, sm_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (binary_order == 99) {
+ if (h5str_dump_simple_data(ENVONLY, stream, attr_id, H5T_STD_REF, sm_buf, (size_t)p_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else {
+ if (h5str_render_bin_output(stream, attr_id, H5T_STD_REF, sm_buf, (size_t)p_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ }
+ else {
+ hsize_t p_nelmts; /* total selected elmts */
+
+ switch (binary_order) {
+ case 1: {
+ if ((p_type = h5str_get_native_type(f_type)) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ break;
+ }
+
+ case 2: {
+ if ((p_type = h5str_get_little_endian_type(f_type)) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ break;
+ }
+
+ case 3: {
+ if ((p_type = h5str_get_big_endian_type(f_type)) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ break;
+ }
+
+ default: {
+ if ((p_type = H5Tcopy(f_type)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ break;
+ }
+ }
+
+ /* Calculate the number of elements we're going to print */
+ p_nelmts = 1;
+
+ if (sndims > 0) {
+ for (i = 0; i < (size_t)sndims; i++)
+ p_nelmts *= total_size[i];
+ } /* end if */
+
+ if (p_nelmts > 0) {
+ /* Check if we have VL data in the dataset's datatype */
+ if (h5str_detect_vlen(p_type) != 0)
+ vl_data = 1;
+
+ alloc_size = (size_t)p_nelmts * H5Tget_size(p_type);
+ if (NULL == (sm_buf = (unsigned char *)HDmalloc((size_t)alloc_size)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_mem: failed to allocate sm_buf");
+
+ /* Read the data */
+ if (H5Aread(attr_id, p_type, sm_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (binary_order == 99) {
+ if (h5str_dump_simple_data(ENVONLY, stream, attr_id, p_type, sm_buf, (size_t)p_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+ else {
+ if (h5str_render_bin_output(stream, attr_id, p_type, sm_buf, (size_t)p_nelmts) < 0)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ }
+
+ /* Reclaim any VL memory, if necessary */
+ if (vl_data) {
+ if (H5Treclaim(p_type, f_space, H5P_DEFAULT, sm_buf) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+ }
+ }
+
+ ret_value = SUCCEED;
+
+done:
+ if (sm_buf)
+ HDfree(sm_buf);
+ if (f_space >= 0)
+ H5Sclose(f_space);
+ if (p_type >= 0)
+ H5Tclose(p_type);
+ if (f_type >= 0)
+ H5Tclose(f_type);
+
+ 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)
+{
+ 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);
+ }
+ }
+
+done:
+ return ret;
+} /* end H5Tdetect_variable_str */
+
+static int
+h5str_dump_simple_data(JNIEnv *env, FILE *stream, hid_t container, hid_t type, void *_mem, hsize_t nelmts)
+{
+ unsigned char *mem = (unsigned char *)_mem;
+ h5str_t buffer; /* string into which to render */
+ hsize_t i; /* element counter */
+ size_t size; /* datum size */
+ int line_count;
+ int ret_value = 0;
+
+ if (!(size = H5Tget_size(type)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ for (i = 0, line_count = 0; i < nelmts; i++, line_count++) {
+ size_t bytes_in = 0; /* # of bytes to write */
+ void *memref = mem + i * size;
+
+ /* Render the data element*/
+ h5str_new(&buffer, 32 * size);
+
+ if (!buffer.s)
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_dump_simple_data: failed to allocate buffer");
+
+ if (!(bytes_in = h5str_sprintf(ENVONLY, &buffer, container, type, memref, 1)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if ((i > 0) && (bytes_in > 0)) {
+ if (HDfprintf(stream, ", ") < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_simple_data: HDfprintf failure");
+
+ if (line_count >= H5TOOLS_TEXT_BLOCK) {
+ line_count = 0;
+
+ if (HDfprintf(stream, "\n") < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_simple_data: HDfprintf failure");
+ }
+ }
+ if (HDfprintf(stream, "%s", buffer.s) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_simple_data: HDfprintf failure");
+
+ h5str_free(&buffer);
+ } /* end for (i = 0; i < nelmts... */
+
+ if (HDfprintf(stream, "\n") < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_simple_data: HDfprintf failure");
+
+done:
+ if (buffer.s)
+ h5str_free(&buffer);
+
+ return ret_value;
+} /* end h5str_dump_simple_data */
+
+/*
+ * Utility Java APIs
+ * Functions designed to workaround issues with the Java-C interface
+ */
+
+/*
+ * Class: hdf_hdf5lib_H5
+ * Method: H5AreadComplex
+ * Signature: (JJ[Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_hdf_hdf5lib_H5_H5AreadComplex(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id,
+ jobjectArray buf)
+{
+ h5str_t h5str;
+ jstring jstr;
+ size_t size;
+ size_t i;
+ hid_t p_type = H5I_INVALID_HID;
+ jsize n;
+ char *readBuf = NULL;
+ herr_t status = FAIL;
+
+ UNUSED(clss);
+
+ HDmemset(&h5str, 0, sizeof(h5str_t));
+
+ if ((p_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ size = (((H5Tget_size(mem_type_id)) > (H5Tget_size(p_type))) ? (H5Tget_size(mem_type_id))
+ : (H5Tget_size(p_type)));
+
+ if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) <= 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5AreadComplex: read buffer length <= 0");
+
+ if (NULL == (readBuf = (char *)HDmalloc((size_t)n * size)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadComplex: failed to allocate read buffer");
+
+ if ((status = H5Aread(attr_id, mem_type_id, readBuf)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ h5str_new(&h5str, 4 * size);
+
+ if (!h5str.s)
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5AreadComplex: failed to allocate string buffer");
+
+ for (i = 0; i < (size_t)n; i++) {
+ h5str.s[0] = '\0';
+
+ if (!h5str_sprintf(ENVONLY, &h5str, attr_id, mem_type_id, readBuf + (i * size), 0))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ if (NULL == (jstr = ENVPTR->NewStringUTF(ENVONLY, h5str.s)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->SetObjectArrayElement(ENVONLY, buf, (jsize)i, jstr);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->DeleteLocalRef(ENVONLY, jstr);
+ } /* end for */
+
+done:
+ if (h5str.s)
+ h5str_free(&h5str);
+ if (readBuf)
+ HDfree(readBuf);
+ if (p_type >= 0)
+ H5Tclose(p_type);
+
+ return status;
+}
+
+/*
+ * Copies the content of one attribute to another attribute
+ * Class: hdf_hdf5lib_H5
+ * Method: H5Acopy
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL
+Java_hdf_hdf5lib_H5_H5Acopy(JNIEnv *env, jclass clss, jlong src_id, jlong dst_id)
+{
+ hssize_t npoints;
+ hsize_t total_size = 0;
+ size_t type_size;
+ jbyte *buf = NULL;
+ hid_t tid = H5I_INVALID_HID;
+ hid_t sid = H5I_INVALID_HID;
+ herr_t retVal = FAIL;
+
+ UNUSED(clss);
+
+ if ((sid = H5Aget_space((hid_t)src_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((tid = H5Aget_type((hid_t)src_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((npoints = H5Sget_simple_extent_npoints(sid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(type_size = H5Tget_size(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ total_size = (hsize_t)npoints * (hsize_t)type_size;
+
+ if (NULL == (buf = (jbyte *)HDmalloc((size_t)total_size * sizeof(jbyte))))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Acopy: failed to allocate buffer");
+
+ if ((retVal = H5Aread((hid_t)src_id, tid, buf)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Tclose(tid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ tid = H5I_INVALID_HID;
+
+ if ((tid = H5Aget_type((hid_t)dst_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((retVal = H5Awrite((hid_t)dst_id, tid, buf)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+done:
+ if (buf)
+ HDfree(buf);
+ if (tid >= 0)
+ H5Tclose(tid);
+ if (sid >= 0)
+ H5Sclose(sid);
+
+ return (jint)retVal;
+} /* end Java_hdf_hdf5lib_H5_H5Acopy */
+
+/*
+ * Copies the content of one dataset to another dataset
+ * Class: hdf_hdf5lib_H5
+ * Method: H5Dcopy
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL
+Java_hdf_hdf5lib_H5_H5Dcopy(JNIEnv *env, jclass clss, jlong src_id, jlong dst_id)
+{
+ hssize_t npoints;
+ hsize_t total_size = 0, total_allocated_size;
+ size_t type_size;
+ jbyte *buf = NULL;
+ hid_t tid = H5I_INVALID_HID;
+ hid_t sid = H5I_INVALID_HID;
+ herr_t retVal = FAIL;
+
+ UNUSED(clss);
+
+ if (!(total_allocated_size = H5Dget_storage_size((hid_t)src_id)))
+ return 0; /* nothing to write */
+
+ if ((sid = H5Dget_space((hid_t)src_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((tid = H5Dget_type((hid_t)src_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((npoints = H5Sget_simple_extent_npoints(sid)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(type_size = H5Tget_size(tid)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ total_size = (hsize_t)npoints * (hsize_t)type_size;
+
+ if (NULL == (buf = (jbyte *)HDmalloc((size_t)total_size * sizeof(jbyte))))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Dcopy: failed to allocate buffer");
+
+ if ((retVal = H5Dread((hid_t)src_id, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if (H5Tclose(tid) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ tid = H5I_INVALID_HID;
+
+ if ((tid = H5Dget_type((hid_t)dst_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((retVal = H5Dwrite((hid_t)dst_id, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+done:
+ if (buf)
+ HDfree(buf);
+ if (tid >= 0)
+ H5Tclose(tid);
+ if (sid >= 0)
+ H5Sclose(sid);
+
+ return (jint)retVal;
+} /* end Java_hdf_hdf5lib_H5_H5Dcopy */
+
+/*
+ * /////////////////////////////////////////////////////////////////////////////////
+ * //
+ * //
+ * // Add these methods so that we don't need to call H5Gget_objtype_by_idx
+ * // in a loop to get information for all the objects in a group, which takes
+ * // a lot of time to finish if the number of objects is more than 10,000
+ * //
+ * /////////////////////////////////////////////////////////////////////////////////
+ */
+
+#ifdef __cplusplus
+herr_t obj_info_all(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data);
+herr_t obj_info_max(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data);
+int H5Gget_obj_info_max(hid_t, char **, int *, int *, H5O_token_t *, long);
+int H5Gget_obj_info_full(hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno,
+ H5O_token_t *obj_token, int indexType, int indexOrder);
+#else
+static herr_t obj_info_all(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data);
+static herr_t obj_info_max(hid_t g_id, const char *name, const H5L_info2_t *linfo, void *op_data);
+static int H5Gget_obj_info_max(hid_t, char **, int *, int *, H5O_token_t *, long);
+static int H5Gget_obj_info_full(hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno,
+ H5O_token_t *obj_token, int indexType, int indexOrder);
+#endif
+
+typedef struct info_all {
+ char **objname;
+ int *otype;
+ int *ltype;
+ H5O_token_t *obj_token;
+ unsigned long *fno;
+ unsigned long idxnum;
+ int count;
+} info_all_t;
+
+/*
+ * Class: hdf_hdf5lib_H5
+ * Method: H5Gget_obj_info_full
+ * Signature: (JLjava/lang/String;[Ljava/lang/String;[I[I[J[JIII)I
+ */
+/*
+ * NOTE: This is a dangerous call! The caller can supply any value they'd like
+ * for 'n' and if it exceeds the number of links in the group, we will most likely
+ * end up overwriting memory heap-tracking info.
+ */
+JNIEXPORT jint JNICALL
+Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full(JNIEnv *env, jclass clss, jlong loc_id, jstring group_name,
+ jobjectArray objName, jintArray oType, jintArray lType,
+ jlongArray fNo, jobjectArray oToken, jint n, jint indx_type,
+ jint indx_order)
+{
+ unsigned long *fnos = NULL;
+ H5O_token_t *tokens = NULL;
+ const char *gName = NULL;
+ char **oName = NULL;
+ jboolean isCopy;
+ jstring str;
+ jobject token;
+ jint *otarr = NULL;
+ jint *ltarr = NULL;
+ jlong *fnoP = NULL;
+ hid_t gid = (hid_t)loc_id;
+ int i;
+ int indexType = indx_type;
+ int indexOrder = indx_order;
+ herr_t ret_val = FAIL;
+
+ UNUSED(clss);
+
+ if (NULL == oType)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: oType is NULL");
+ if (NULL == lType)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: lType is NULL");
+ if (NULL == oToken)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: oToken is NULL");
+ if (NULL == fNo)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: fNo is NULL");
+
+ PIN_INT_ARRAY(ENVONLY, oType, otarr, &isCopy, "H5Gget_obj_info_full: oType not pinned");
+ PIN_INT_ARRAY(ENVONLY, lType, ltarr, &isCopy, "H5Gget_obj_info_full: lType not pinned");
+ PIN_LONG_ARRAY(ENVONLY, fNo, fnoP, &isCopy, "H5Gget_obj_info_full: fNo not pinned");
+
+ if (NULL == (oName = (char **)HDcalloc((size_t)n, sizeof(*oName))))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for object name");
+
+ if (NULL == (tokens = (H5O_token_t *)HDcalloc((size_t)n, sizeof(H5O_token_t))))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for object tokens");
+
+ if (NULL == (fnos = (unsigned long *)HDcalloc((size_t)n, sizeof(unsigned long))))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "H5Gget_obj_info_full: failed to allocate buffer for file number info");
+
+ if (group_name) {
+ PIN_JAVA_STRING(ENVONLY, group_name, gName, &isCopy, "H5Gget_obj_info_full: group_name not pinned");
+
+ if ((gid = H5Gopen2((hid_t)loc_id, gName, H5P_DEFAULT)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ }
+
+ if ((ret_val = H5Gget_obj_info_full(gid, oName, (int *)otarr, (int *)ltarr, fnos, tokens, indexType,
+ indexOrder)) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: retrieval of object info failed");
+
+ for (i = 0; i < n; i++) {
+ fnoP[i] = (jlong)fnos[i];
+
+ if (oName[i]) {
+ if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, oName[i])))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->SetObjectArrayElement(ENVONLY, objName, i, (jobject)str);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->DeleteLocalRef(ENVONLY, str);
+ } /* end if */
+
+ /* Create an H5O_token_t object */
+ if (NULL == (token = create_H5O_token_t(ENVONLY, &tokens[i], TRUE)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->SetObjectArrayElement(ENVONLY, oToken, i, token);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->DeleteLocalRef(ENVONLY, token);
+ }
+
+done:
+ if (gName) {
+ H5Gclose(gid);
+ UNPIN_JAVA_STRING(ENVONLY, group_name, gName);
+ }
+ if (fnos)
+ HDfree(fnos);
+ if (tokens)
+ HDfree(tokens);
+ if (oName)
+ h5str_array_free(oName, (size_t)n);
+ if (fnoP)
+ UNPIN_LONG_ARRAY(ENVONLY, fNo, fnoP, (ret_val < 0) ? JNI_ABORT : 0);
+ if (ltarr)
+ UNPIN_INT_ARRAY(ENVONLY, lType, ltarr, (ret_val < 0) ? JNI_ABORT : 0);
+ if (otarr)
+ UNPIN_INT_ARRAY(ENVONLY, oType, otarr, (ret_val < 0) ? JNI_ABORT : 0);
+
+ return ret_val;
+} /* end Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full */
+
+/*
+ * Class: hdf_hdf5lib_H5
+ * Method: H5Gget_obj_info_max
+ * Signature: (J[Ljava/lang/String;[I[I[JJI)I
+ */
+/*
+ * NOTE: This is a dangerous call! The caller can supply any value they'd like
+ * for 'n' and if it exceeds the number of links reachable from the group, we
+ * will most likely end up overwriting memory heap-tracking info.
+ */
+JNIEXPORT jint JNICALL
+Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1max(JNIEnv *env, jclass clss, jlong loc_id, jobjectArray objName,
+ jintArray oType, jintArray lType, jobjectArray oToken,
+ jlong maxnum, jint n)
+{
+ H5O_token_t *tokens = NULL;
+ jboolean isCopy;
+ jstring str;
+ jobject token;
+ char **oName = NULL;
+ jint *otarr = NULL;
+ jint *ltarr = NULL;
+ int i;
+ herr_t ret_val = FAIL;
+
+ UNUSED(clss);
+
+ if (NULL == oType)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: oType is NULL");
+ if (NULL == lType)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: lType is NULL");
+ if (NULL == oToken)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: oToken is NULL");
+
+ PIN_INT_ARRAY(ENVONLY, oType, otarr, &isCopy, "H5Gget_obj_info_max: oType not pinned");
+ PIN_INT_ARRAY(ENVONLY, lType, ltarr, &isCopy, "H5Gget_obj_info_max: lType not pinned");
+
+ if (NULL == (oName = (char **)HDcalloc((size_t)n, sizeof(*oName))))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_max: failed to allocate buffer for object name");
+
+ if (NULL == (tokens = (H5O_token_t *)HDcalloc((size_t)n, sizeof(H5O_token_t))))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Gget_obj_info_max: failed to allocate buffer for object tokens");
+
+ if ((ret_val = H5Gget_obj_info_max((hid_t)loc_id, oName, (int *)otarr, (int *)ltarr, tokens, maxnum)) < 0)
+ H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_max: retrieval of object info failed");
+
+ for (i = 0; i < n; i++) {
+ if (oName[i]) {
+ if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, oName[i])))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->SetObjectArrayElement(ENVONLY, objName, i, (jobject)str);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->DeleteLocalRef(ENVONLY, str);
+ }
+
+ /* Create an H5O_token_t object */
+ if (NULL == (token = create_H5O_token_t(ENVONLY, &tokens[i], TRUE)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->SetObjectArrayElement(ENVONLY, oToken, i, token);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ ENVPTR->DeleteLocalRef(ENVONLY, token);
+ } /* end for */
+
+done:
+ if (tokens)
+ HDfree(tokens);
+ if (oName)
+ h5str_array_free(oName, (size_t)n);
+ if (ltarr)
+ UNPIN_INT_ARRAY(ENVONLY, lType, ltarr, (ret_val < 0) ? JNI_ABORT : 0);
+ if (otarr)
+ UNPIN_INT_ARRAY(ENVONLY, oType, otarr, (ret_val < 0) ? JNI_ABORT : 0);
+
+ return ret_val;
+} /* end Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1max */
+
+int
+H5Gget_obj_info_full(hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno,
+ H5O_token_t *obj_token, int indexType, int indexOrder)
+{
+ info_all_t info;
+
+ info.objname = objname;
+ info.otype = otype;
+ info.ltype = ltype;
+ info.idxnum = 0;
+ info.fno = fno;
+ info.obj_token = obj_token;
+ info.count = 0;
+
+ if (H5Literate2(loc_id, (H5_index_t)indexType, (H5_iter_order_t)indexOrder, NULL, obj_info_all,
+ (void *)&info) < 0) {
+ /*
+ * Reset info stats; most importantly, reset the count.
+ */
+ info.objname = objname;
+ info.otype = otype;
+ info.ltype = ltype;
+ info.idxnum = 0;
+ info.fno = fno;
+ info.obj_token = obj_token;
+ info.count = 0;
+
+ /* Iteration failed, try normal alphabetical order */
+ if (H5Literate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, obj_info_all, (void *)&info) < 0)
+ return -1;
+ }
+
+ return info.count;
+} /* end H5Gget_obj_info_full */
+
+int
+H5Gget_obj_info_max(hid_t loc_id, char **objname, int *otype, int *ltype, H5O_token_t *obj_token, long maxnum)
+{
+ info_all_t info;
+
+ info.objname = objname;
+ info.otype = otype;
+ info.ltype = ltype;
+ info.idxnum = (unsigned long)maxnum;
+ info.obj_token = obj_token;
+ info.count = 0;
+
+ if (H5Lvisit2(loc_id, H5_INDEX_NAME, H5_ITER_NATIVE, obj_info_max, (void *)&info) < 0)
+ return -1;
+
+ return info.count;
+} /* end H5Gget_obj_info_max */
+
+herr_t
+obj_info_all(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_data)
+{
+ info_all_t *datainfo = (info_all_t *)op_data;
+ H5O_info2_t object_info;
+ htri_t object_exists;
+
+ datainfo->otype[datainfo->count] = -1;
+ datainfo->ltype[datainfo->count] = -1;
+ datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF;
+
+ if (NULL == (datainfo->objname[datainfo->count] = HDstrdup(name)))
+ goto done;
+
+ if ((object_exists = H5Oexists_by_name(loc_id, name, H5P_DEFAULT)) < 0)
+ goto done;
+
+ if (object_exists) {
+ if (H5Oget_info_by_name3(loc_id, name, &object_info, H5O_INFO_ALL, H5P_DEFAULT) < 0)
+ goto done;
+
+ datainfo->otype[datainfo->count] = object_info.type;
+ datainfo->ltype[datainfo->count] = info->type;
+ datainfo->fno[datainfo->count] = object_info.fileno;
+
+ HDmemcpy(&datainfo->obj_token[datainfo->count], &object_info.token, sizeof(object_info.token));
+ }
+
+done:
+ datainfo->count++;
+
+ return SUCCEED;
+} /* end obj_info_all */
+
+herr_t
+obj_info_max(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_data)
+{
+ info_all_t *datainfo = (info_all_t *)op_data;
+ H5O_info2_t object_info;
+
+ datainfo->otype[datainfo->count] = -1;
+ datainfo->ltype[datainfo->count] = -1;
+ datainfo->objname[datainfo->count] = NULL;
+ datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF;
+
+ /* This will be freed by h5str_array_free(oName, n) */
+ if (NULL == (datainfo->objname[datainfo->count] = HDstrdup(name)))
+ goto done;
+
+ if (H5Oget_info3(loc_id, &object_info, H5O_INFO_ALL) < 0)
+ goto done;
+
+ datainfo->otype[datainfo->count] = object_info.type;
+ datainfo->ltype[datainfo->count] = info->type;
+
+ HDmemcpy(&datainfo->obj_token[datainfo->count], &object_info.token, sizeof(object_info.token));
+
+done:
+ datainfo->count++;
+
+ if (datainfo->count >= (int)datainfo->idxnum)
+ return 1;
+ else
+ return SUCCEED;
+} /* end obj_info_max */
+
+/*
+ * Class: hdf_hdf5lib_H5
+ * Method: H5export_dataset
+ * Signature: (Ljava/lang/String;JLjava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL
+Java_hdf_hdf5lib_H5_H5export_1dataset(JNIEnv *env, jclass clss, jstring file_export_name, jlong file_id,
+ jstring object_path, jint binary_order)
+{
+ const char *file_export = NULL;
+ const char *object_name = NULL;
+ jboolean isCopy;
+ herr_t ret_val = FAIL;
+ hid_t dataset_id = H5I_INVALID_HID;
+ FILE *stream = NULL;
+
+ UNUSED(clss);
+
+ if (NULL == file_export_name)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5export_dataset: file_export_name is NULL");
+
+ if (NULL == object_path)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5export_dataset: object_path is NULL");
+
+ PIN_JAVA_STRING(ENVONLY, object_path, object_name, &isCopy, "H5export_dataset: object_path not pinned");
+
+ if ((dataset_id = H5Dopen2(file_id, object_name, H5P_DEFAULT)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ PIN_JAVA_STRING(ENVONLY, file_export_name, file_export, NULL,
+ "H5export_dataset: file_export name not pinned");
+
+ if (NULL == (stream = HDfopen(file_export, "w+")))
+ H5_JNI_FATAL_ERROR(ENVONLY, "HDfopen failed");
+
+ if ((ret_val = h5str_dump_simple_dset(ENVONLY, stream, dataset_id, binary_order)) < 0)
+ H5_ASSERTION_ERROR(ENVONLY, "h5str_dump_simple_dset failed");
+
+ if (stream) {
+ HDfclose(stream);
+ stream = NULL;
+ }
+
+done:
+ if (stream)
+ HDfclose(stream);
+ if (file_export)
+ UNPIN_JAVA_STRING(ENVONLY, file_export_name, file_export);
+ if (object_name)
+ UNPIN_JAVA_STRING(ENVONLY, object_path, object_name);
+ if (dataset_id >= 0)
+ H5Dclose(dataset_id);
+} /* end Java_hdf_hdf5lib_H5_H5export_1dataset */
+
+/*
+ * Class: hdf_hdf5lib_H5
+ * Method: H5export_attribute
+ * Signature: (Ljava/lang/String;JLjava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL
+Java_hdf_hdf5lib_H5_H5export_1attribute(JNIEnv *env, jclass clss, jstring file_export_name, jlong dset_id,
+ jstring attribute_name, jint binary_order)
+{
+ const char *file_export = NULL;
+ const char *object_name = NULL;
+ jboolean isCopy;
+ herr_t ret_val = FAIL;
+ hid_t attr_id = H5I_INVALID_HID;
+ FILE *stream = NULL;
+
+ UNUSED(clss);
+
+ if (NULL == file_export_name)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5export_dataset: file_export_name is NULL");
+
+ if (NULL == attribute_name)
+ H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5export_dataset: object_path is NULL");
+
+ PIN_JAVA_STRING(ENVONLY, attribute_name, object_name, &isCopy,
+ "H5export_dataset: object_path not pinned");
+
+ if ((attr_id = H5Aopen(dset_id, object_name, H5P_DEFAULT)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ PIN_JAVA_STRING(ENVONLY, file_export_name, file_export, NULL,
+ "H5export_dataset: file_export name not pinned");
+
+ if (NULL == (stream = HDfopen(file_export, "w+")))
+ H5_JNI_FATAL_ERROR(ENVONLY, "HDfopen failed");
+
+ if ((ret_val = h5str_dump_simple_mem(ENVONLY, stream, attr_id, binary_order)) < 0)
+ H5_ASSERTION_ERROR(ENVONLY, "h5str_dump_simple_dset failed");
+
+ if (stream) {
+ HDfclose(stream);
+ stream = NULL;
+ }
+
+done:
+ if (stream)
+ HDfclose(stream);
+ if (file_export)
+ UNPIN_JAVA_STRING(ENVONLY, file_export_name, file_export);
+ if (object_name)
+ UNPIN_JAVA_STRING(ENVONLY, attribute_name, object_name);
+ if (attr_id >= 0)
+ H5Aclose(attr_id);
+} /* end Java_hdf_hdf5lib_H5_H5export_1attribute */
+
+jobject
+translate_atomic_rbuf(JNIEnv *env, jobject ret_buf, jlong mem_type_id, H5T_class_t type_class, void *raw_buf)
+{
+ jobject jobj = NULL;
+ hid_t memb = H5I_INVALID_HID;
+ int ret_buflen = -1;
+ jboolean found_jList = JNI_TRUE;
+ jobjectArray jList = NULL;
+ H5T_class_t vlClass;
+ size_t vlSize;
+ size_t i, x;
+ size_t typeSize;
+ // raw_buf is normally bytes except when used for variable length strings
+ char *char_buf = (char *)raw_buf;
+
+ /* retrieve the java.util.ArrayList interface class */
+ jclass arrCList = ENVPTR->FindClass(ENVONLY, "java/util/ArrayList");
+ jmethodID arrListMethod = ENVPTR->GetMethodID(ENVONLY, arrCList, "<init>", "(I)V");
+ jmethodID arrAddMethod = ENVPTR->GetMethodID(ENVONLY, arrCList, "add", "(Ljava/lang/Object;)Z");
+
+ /* 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");
+ /*jobjectArray
+ 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;");
+
+ if (!(typeSize = H5Tget_size(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ ret_buflen = ENVPTR->GetArrayLength(ENVONLY, ret_buf);
+ switch (type_class) {
+ case H5T_VLEN: {
+ if (!(memb = H5Tget_super(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Convert element to a list */
+ hvl_t vl_elem;
+
+ found_jList = JNI_TRUE;
+ jList = NULL;
+
+ /* Get the number of sequence elements */
+ HDmemcpy(&vl_elem, char_buf, sizeof(hvl_t));
+ jsize nelmts = (jsize)vl_elem.len;
+ if (vl_elem.len != (size_t)nelmts)
+ H5_JNI_FATAL_ERROR(ENVONLY, "translate_atomic_rbuf: overflow of number of VL elements");
+
+ if (nelmts < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "translate_atomic_rbuf: number of VL elements < 0");
+
+ /* The list we're going to return: */
+ if (NULL == (jList = (jobjectArray)ENVPTR->NewObject(ENVONLY, arrCList, arrListMethod, 0)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_rbuf: failed to allocate list read buffer");
+
+ translate_rbuf(ENVONLY, jList, memb, vlClass, (jsize)nelmts, vl_elem.p);
+ jobj = jList;
+ break;
+ } /* H5T_VLEN */
+ case H5T_COMPOUND: {
+ int nmembs = H5Tget_nmembers(mem_type_id);
+ void *objBuf = NULL;
+
+ /* The list we're going to return: */
+ if (NULL == (jList = (jobjectArray)ENVPTR->NewObject(ENVONLY, arrCList, arrListMethod, 0)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_rbuf: failed to allocate list read buffer");
+
+ /* Convert each element to a compound object */
+ for (i = 0; i < (size_t)nmembs; i++) {
+ H5T_class_t memb_vlClass;
+ size_t memb_vlSize;
+ size_t memb_offset;
+
+ if ((memb = H5Tget_member_type(mem_type_id, (unsigned int)i)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((memb_offset = H5Tget_member_offset(mem_type_id, (unsigned int)i)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((memb_vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(memb_vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ translate_atomic_rbuf(ENVONLY, jList, memb, memb_vlClass,
+ char_buf + i * typeSize + memb_offset);
+ H5Tclose(memb);
+ }
+ jobj = jList;
+ break;
+ } /* H5T_COMPOUND */
+ case H5T_ARRAY: {
+ void *objBuf = NULL;
+ size_t typeCount;
+
+ if (!(memb = H5Tget_super(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(typeSize = H5Tget_size(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ typeCount = typeSize / vlSize;
+
+ if (NULL == (objBuf = HDmalloc(typeSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_rbuf: failed to allocate buffer");
+
+ /* Convert each element */
+ /* Get the object element */
+ HDmemcpy((char *)objBuf, char_buf, typeSize);
+
+ /* The list we're going to return: */
+ if (NULL == (jList = (jobjectArray)ENVPTR->NewObject(ENVONLY, arrCList, arrListMethod, 0)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_rbuf: failed to allocate list read buffer");
+
+ translate_rbuf(ENVONLY, jList, memb, vlClass, (jsize)typeCount, objBuf);
+ jobj = jList;
+
+ if (objBuf)
+ HDfree(objBuf);
+
+ break;
+ } /* H5T_ARRAY */
+ case H5T_ENUM:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_INTEGER: {
+ /* Convert each element */
+ switch (typeSize) {
+ case sizeof(jbyte): {
+ jbyte byteValue;
+ HDmemcpy(((char *)&byteValue), char_buf, typeSize);
+
+ if (NULL ==
+ (jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cByte, byteValueMid, byteValue)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ }
+ case sizeof(jshort): {
+ jshort shortValue;
+ HDmemcpy(((char *)&shortValue), char_buf, typeSize);
+
+ if (NULL ==
+ (jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cShort, shortValueMid, shortValue)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ }
+ case sizeof(jint): {
+ jint intValue;
+
+ HDmemcpy(((char *)&intValue), char_buf, typeSize);
+
+ if (NULL == (jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cInt, intValueMid, intValue)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ }
+ case sizeof(jlong): {
+ jlong longValue;
+ HDmemcpy(((char *)&longValue), char_buf, typeSize);
+
+ if (NULL ==
+ (jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cLong, longValueMid, longValue)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ }
+ }
+ break;
+ } /* H5T_INTEGER */
+ case H5T_FLOAT: {
+ /* Convert each element to a list */
+ switch (typeSize) {
+ case sizeof(jfloat): {
+ jfloat floatValue;
+ HDmemcpy(((char *)&floatValue), char_buf, typeSize);
+
+ if (NULL == (jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cFloat, floatValueMid,
+ (double)floatValue)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ }
+ case sizeof(jdouble): {
+ jdouble doubleValue;
+ HDmemcpy(((char *)&doubleValue), char_buf, typeSize);
+
+ if (NULL == (jobj = ENVPTR->CallStaticObjectMethod(ENVONLY, cDouble, doubleValueMid,
+ doubleValue)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ break;
+ }
+ }
+ break;
+ } /* H5T_FLOAT */
+ case H5T_REFERENCE: {
+ /* Convert each element to a list */
+ jboolean bb;
+ jbyte *barray = NULL;
+
+ jsize byteArraySize = (jsize)typeSize;
+ if (typeSize != (size_t)byteArraySize)
+ H5_JNI_FATAL_ERROR(ENVONLY, "translate_atomic_rbuf: overflow of byteArraySize");
+
+ if (NULL == (jobj = ENVPTR->NewByteArray(ENVONLY, byteArraySize)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ PIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, &bb,
+ "translate_atomic_rbuf reference: byte array not pinned");
+
+ HDmemcpy(barray, ((jbyte *)raw_buf), typeSize);
+ if (barray)
+ UNPIN_BYTE_ARRAY(ENVONLY, (jbyteArray)jobj, barray, jobj ? 0 : JNI_ABORT);
+
+ break;
+ } /* H5T_REFERENCE */
+ case H5T_STRING: {
+ htri_t is_variable = 0;
+
+ if ((is_variable = H5Tis_variable_str(mem_type_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Convert each element */
+ if (is_variable) {
+ char **var_str_buf = (char **)raw_buf;
+ if (NULL == (jobj = ENVPTR->NewStringUTF(ENVONLY, *var_str_buf))) {
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_rbuf: out of memory - unable to "
+ "construct string from UTF characters");
+ }
+ }
+ else {
+ if (NULL == (jobj = ENVPTR->NewStringUTF(ENVONLY, char_buf))) {
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_rbuf: out of memory - unable to "
+ "construct string from UTF characters");
+ }
+ }
+
+ break;
+ } /* H5T_STRING */
+ default:
+ H5_UNIMPLEMENTED(ENVONLY, "translate_atomic_rbuf: invalid class type");
+ break;
+ } /* switch(type_class) */
+
+done:
+
+ return jobj;
+}
+
+void
+translate_atomic_wbuf(JNIEnv *env, jobject in_obj, jlong mem_type_id, H5T_class_t type_class, void *raw_buf)
+{
+ hid_t memb = H5I_INVALID_HID;
+ H5T_class_t vlClass;
+ size_t vlSize;
+ size_t i, x;
+ size_t typeSize;
+ // raw_buf is normally bytes except when used for variable length strings
+ char *char_buf = (char *)raw_buf;
+
+ /* retrieve the java.util.ArrayList interface class */
+ jclass arrCList = ENVPTR->FindClass(ENVONLY, "java/util/ArrayList");
+ /* retrieve the toArray method */
+ jmethodID mToArray = ENVPTR->GetMethodID(ENVONLY, arrCList, "toArray", "()[Ljava/lang/Object;");
+
+ /* Cache class types */
+ 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 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");
+
+ if (!(typeSize = H5Tget_size(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ switch (type_class) {
+ case H5T_VLEN: {
+ 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);
+
+ /* Convert element to a vlen element */
+ hvl_t vl_elem;
+
+ jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, in_obj);
+
+ if (jnelmts < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "translate_atomic_wbuf: number of VL elements < 0");
+
+ vl_elem.len = (size_t)jnelmts;
+
+ if (NULL == (vl_elem.p = HDmalloc((size_t)jnelmts * vlSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_wbuf: failed to allocate vlen ptr buffer");
+
+ translate_wbuf(ENVONLY, (jobjectArray)in_obj, memb, vlClass, (jsize)jnelmts, vl_elem.p);
+
+ HDmemcpy(char_buf, &vl_elem, sizeof(hvl_t));
+ break;
+ } /* H5T_VLEN */
+ case H5T_COMPOUND: {
+ void *objBuf = NULL;
+
+ /* Convert each compound element */
+ int nmembs = H5Tget_nmembers(mem_type_id);
+
+ /* invoke the toArray method */
+ if (mToArray == NULL)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, in_obj, mToArray);
+ jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array);
+
+ if (jnelmts != nmembs)
+ H5_BAD_ARGUMENT_ERROR(
+ ENVONLY, "translate_atomic_wbuf: number of elements not equal to number of members");
+
+ /* Convert each compound object to an element */
+ for (i = 0; i < (size_t)nmembs; i++) {
+ H5T_class_t memb_vlClass;
+ size_t memb_vlSize;
+ size_t memb_offset;
+
+ if ((memb = H5Tget_member_type(mem_type_id, (unsigned int)i)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((memb_offset = H5Tget_member_offset(mem_type_id, (unsigned int)i)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((memb_vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(memb_vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ jobject arr_obj = ENVPTR->GetObjectArrayElement(ENVONLY, array, i);
+ translate_atomic_wbuf(ENVONLY, arr_obj, memb, memb_vlClass,
+ char_buf + i * typeSize + memb_offset);
+ ENVPTR->DeleteLocalRef(ENVONLY, arr_obj);
+ H5Tclose(memb);
+ }
+ break;
+ } /* H5T_COMPOUND */
+ case H5T_ARRAY: {
+ void *objBuf = NULL;
+
+ if (!(memb = H5Tget_super(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Convert each array element */
+ /* invoke the toArray method */
+ if (mToArray == NULL)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, in_obj, mToArray);
+ jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array);
+
+ if (jnelmts < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "translate_atomic_wbuf: number of array elements < 0");
+
+ if (NULL == (objBuf = HDmalloc((size_t)jnelmts * vlSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_atomic_wbuf: failed to allocate buffer");
+
+ translate_wbuf(ENVONLY, array, memb, vlClass, (jsize)jnelmts, objBuf);
+
+ HDmemcpy(char_buf, (char *)objBuf, vlSize * jnelmts);
+ break;
+ } /* H5T_ARRAY */
+ case H5T_ENUM:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_INTEGER: {
+ /* Convert each element */
+ switch (typeSize) {
+ case sizeof(jbyte): {
+ jbyte byteValue = ENVPTR->CallByteMethod(ENVONLY, in_obj, byteValueMid);
+ HDmemcpy(char_buf, ((char *)&byteValue), typeSize);
+ }
+ case sizeof(jshort): {
+ jshort shortValue = ENVPTR->CallShortMethod(ENVONLY, in_obj, shortValueMid);
+ HDmemcpy(char_buf, ((char *)&shortValue), typeSize);
+ break;
+ }
+ case sizeof(jint): {
+ jint intValue = ENVPTR->CallIntMethod(ENVONLY, in_obj, intValueMid);
+ HDmemcpy(char_buf, ((char *)&intValue), typeSize);
+ break;
+ }
+ case sizeof(jlong): {
+ jlong longValue = ENVPTR->CallLongMethod(ENVONLY, in_obj, longValueMid);
+ HDmemcpy(char_buf, ((char *)&longValue), typeSize);
+ break;
+ }
+ }
+ break;
+ } /* H5T_INTEGER */
+ case H5T_FLOAT: {
+ /* Convert each element */
+ switch (typeSize) {
+ case sizeof(jfloat): {
+ jfloat floatValue = ENVPTR->CallFloatMethod(ENVONLY, in_obj, floatValueMid);
+ HDmemcpy(char_buf, ((char *)&floatValue), typeSize);
+ break;
+ }
+ case sizeof(jdouble): {
+ jdouble doubleValue = ENVPTR->CallDoubleMethod(ENVONLY, in_obj, doubleValueMid);
+ HDmemcpy(char_buf, ((char *)&doubleValue), typeSize);
+ break;
+ }
+ }
+ break;
+ } /* H5T_FLOAT */
+ case H5T_REFERENCE: {
+ /* Convert each array element */
+ jbyte *barray = (jbyte *)ENVPTR->GetByteArrayElements(ENVONLY, in_obj, 0);
+ HDmemcpy(char_buf, ((char *)barray), typeSize);
+ ENVPTR->ReleaseByteArrayElements(ENVONLY, in_obj, barray, 0);
+ break;
+ } /* H5T_REFERENCE */
+ case H5T_STRING: {
+ htri_t is_variable = 0;
+
+ if ((is_variable = H5Tis_variable_str(mem_type_id)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Convert each pointer element */
+ jsize length;
+ const char *utf8 = NULL;
+
+ HDmemset(char_buf, 0, typeSize);
+ if (NULL != in_obj) {
+ PIN_JAVA_STRING(ENVONLY, in_obj, utf8, NULL, "translate_atomic_wbuf jobj not pinned");
+ length = ENVPTR->GetStringUTFLength(ENVONLY, in_obj);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ if (is_variable) {
+ char *new_buf = (char *)HDcalloc((size_t)1, length + 1);
+ HDmemcpy(((char *)new_buf), utf8, length);
+ HDmemcpy(char_buf, &new_buf, typeSize);
+ }
+ else {
+ HDmemcpy(char_buf, utf8, length);
+ }
+ UNPIN_JAVA_STRING(ENVONLY, in_obj, utf8);
+ utf8 = NULL;
+ }
+ break;
+ } /* H5T_STRING */
+ default:
+ H5_UNIMPLEMENTED(ENVONLY, "translate_atomic_wbuf: invalid class type");
+ break;
+ } /* switch(type_class) */
+
+done:
+
+ return;
+}
+
+void
+translate_rbuf(JNIEnv *env, jobjectArray ret_buf, jlong mem_type_id, H5T_class_t type_class, jsize count,
+ void *raw_buf)
+{
+ hid_t memb = H5I_INVALID_HID;
+ int ret_buflen = -1;
+ jboolean found_jList = JNI_TRUE;
+ jobjectArray jList = NULL;
+ jobject jobj = NULL;
+ H5T_class_t vlClass;
+ size_t vlSize;
+ size_t i, x;
+ size_t typeSize;
+ // raw_buf is normally bytes except when used for variable length strings
+ char *char_buf = (char *)raw_buf;
+
+ /* retrieve the java.util.ArrayList interface class */
+ jclass arrCList = ENVPTR->FindClass(ENVONLY, "java/util/ArrayList");
+ jmethodID arrListMethod = ENVPTR->GetMethodID(ENVONLY, arrCList, "<init>", "(I)V");
+ jmethodID arrAddMethod = ENVPTR->GetMethodID(ENVONLY, arrCList, "add", "(Ljava/lang/Object;)Z");
+
+ /* Cache class types */
+ 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 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;");
+
+ if (!(typeSize = H5Tget_size(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ ret_buflen = ENVPTR->GetArrayLength(ENVONLY, ret_buf);
+ switch (type_class) {
+ case H5T_VLEN: {
+ if (!(memb = H5Tget_super(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Convert each element to a list */
+ for (i = 0; i < (size_t)count; i++) {
+ hvl_t vl_elem;
+
+ found_jList = JNI_TRUE;
+ jList = NULL;
+
+ /* Get the number of sequence elements */
+ HDmemcpy(&vl_elem, char_buf + i * sizeof(hvl_t), sizeof(hvl_t));
+ jsize nelmts = (jsize)vl_elem.len;
+ if (vl_elem.len != (size_t)nelmts)
+ H5_JNI_FATAL_ERROR(ENVONLY, "translate_rbuf: overflow of number of VL elements");
+
+ if (nelmts < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "translate_rbuf: number of VL elements < 0");
+
+ /* The list we're going to return: */
+ if (i < ret_buflen) {
+ jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)ret_buf, (jsize)i);
+ }
+ if (NULL == jList) {
+ found_jList = JNI_FALSE;
+ if (NULL ==
+ (jList = (jobjectArray)ENVPTR->NewObject(ENVONLY, arrCList, arrListMethod, 0)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "translate_rbuf: failed to allocate list read buffer");
+ }
+
+ translate_rbuf(ENVONLY, jList, memb, vlClass, (jsize)nelmts, vl_elem.p);
+ int jListlen = ENVPTR->GetArrayLength(ENVONLY, jList);
+ if (found_jList == JNI_FALSE) {
+ jboolean addResult =
+ ENVPTR->CallBooleanMethod(ENVONLY, ret_buf, arrAddMethod, (jobject)jList);
+ if (!addResult)
+ H5_JNI_FATAL_ERROR(ENVONLY, "translate_rbuf: cannot add VL element");
+ }
+ else {
+ ENVPTR->SetObjectArrayElement(ENVONLY, ret_buf, i, (jobject)jList);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
+ }
+ ENVPTR->DeleteLocalRef(ENVONLY, jList);
+ }
+ break;
+ } /* H5T_VLEN */
+ case H5T_COMPOUND: {
+ void *objBuf = NULL;
+
+ /* Convert each compound element to a list */
+ for (i = 0; i < (size_t)count; i++) {
+ found_jList = JNI_TRUE;
+ jList = NULL;
+
+ /* The list we're going to return: */
+ if (i < ret_buflen) {
+ jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)ret_buf, (jsize)i);
+ }
+ if (NULL == jList) {
+ found_jList = JNI_FALSE;
+ if (NULL ==
+ (jList = (jobjectArray)ENVPTR->NewObject(ENVONLY, arrCList, arrListMethod, 0)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "translate_rbuf: failed to allocate list read buffer");
+ }
+ int nmembs = H5Tget_nmembers(mem_type_id);
+ /* Convert each element to a list */
+ for (x = 0; x < (size_t)nmembs; x++) {
+ H5T_class_t memb_vlClass;
+ size_t memb_vlSize;
+ size_t memb_offset;
+
+ if ((memb = H5Tget_member_type(mem_type_id, (unsigned int)x)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((memb_offset = H5Tget_member_offset(mem_type_id, (unsigned int)x)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((memb_vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(memb_vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ jobj = translate_atomic_rbuf(ENVONLY, jList, memb, memb_vlClass,
+ char_buf + i * typeSize + memb_offset);
+ if (jobj) {
+ if (found_jList == JNI_FALSE)
+ ENVPTR->CallBooleanMethod(ENVONLY, jList, arrAddMethod, (jobject)jobj);
+ else
+ ENVPTR->SetObjectArrayElement(ENVONLY, jList, i, (jobject)jobj);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
+ ENVPTR->DeleteLocalRef(ENVONLY, jobj);
+ }
+
+ H5Tclose(memb);
+ }
+ if (ret_buflen == 0)
+ ENVPTR->CallBooleanMethod(ENVONLY, ret_buf, arrAddMethod, jList);
+ else
+ ENVPTR->SetObjectArrayElement(ENVONLY, ret_buf, i, jList);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
+ ENVPTR->DeleteLocalRef(ENVONLY, jList);
+ }
+ break;
+ } /* H5T_COMPOUND */
+ case H5T_ARRAY: {
+ void *objBuf = NULL;
+ size_t typeCount;
+
+ if (!(memb = H5Tget_super(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(typeSize = H5Tget_size(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ typeCount = typeSize / vlSize;
+
+ if (NULL == (objBuf = HDmalloc(typeSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_rbuf: failed to allocate buffer");
+
+ /* Convert each element to a list */
+ for (i = 0; i < (size_t)count; i++) {
+ found_jList = JNI_TRUE;
+ jList = NULL;
+
+ /* Get the object element */
+ HDmemcpy((char *)objBuf, char_buf + i * typeSize, typeSize);
+
+ /* The list we're going to return: */
+ if (i < ret_buflen) {
+ if (NULL ==
+ (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)ret_buf, (jsize)i)))
+ found_jList = JNI_FALSE;
+ }
+ if (NULL == jList) {
+ if (NULL ==
+ (jList = (jobjectArray)ENVPTR->NewObject(ENVONLY, arrCList, arrListMethod, 0)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY,
+ "translate_rbuf: failed to allocate list read buffer");
+ }
+
+ translate_rbuf(ENVONLY, jList, memb, vlClass, (jsize)typeCount, objBuf);
+ if (found_jList == JNI_FALSE)
+ ENVPTR->CallBooleanMethod(ENVONLY, ret_buf, arrAddMethod, jList);
+ else
+ ENVPTR->SetObjectArrayElement(ENVONLY, ret_buf, i, jList);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
+ ENVPTR->DeleteLocalRef(ENVONLY, jList);
+ }
+
+ if (objBuf)
+ HDfree(objBuf);
+
+ break;
+ } /* H5T_ARRAY */
+ case H5T_ENUM:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_REFERENCE:
+ case H5T_STRING: {
+ /* Convert each element to a list */
+ for (i = 0; i < (size_t)count; i++) {
+ jobj =
+ translate_atomic_rbuf(ENVONLY, ret_buf, mem_type_id, type_class, char_buf + i * typeSize);
+ if (jobj) {
+ if (ret_buflen == 0)
+ ENVPTR->CallBooleanMethod(ENVONLY, ret_buf, arrAddMethod, (jobject)jobj);
+ else
+ ENVPTR->SetObjectArrayElement(ENVONLY, ret_buf, i, (jobject)jobj);
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE);
+ ENVPTR->DeleteLocalRef(ENVONLY, jobj);
+ }
+ }
+ break;
+ }
+ default:
+ H5_UNIMPLEMENTED(ENVONLY, "translate_rbuf: invalid class type");
+ break;
+ } /* switch(type_class) */
+
+done:
+
+ return;
+}
+
+void
+translate_wbuf(JNIEnv *env, jobjectArray in_buf, jlong mem_type_id, H5T_class_t type_class, jsize count,
+ void *raw_buf)
+{
+ hid_t memb = H5I_INVALID_HID;
+ jobjectArray jList = NULL;
+ jobject jobj = NULL;
+ H5T_class_t vlClass;
+ size_t vlSize;
+ size_t i, x;
+ size_t typeSize;
+ // raw_buf is normally bytes except when used for variable length strings
+ char *char_buf = (char *)raw_buf;
+
+ /* retrieve the java.util.ArrayList interface class */
+ jclass arrCList = ENVPTR->FindClass(ENVONLY, "java/util/ArrayList");
+ /* retrieve the toArray method */
+ jmethodID mToArray = ENVPTR->GetMethodID(ENVONLY, arrCList, "toArray", "()[Ljava/lang/Object;");
+
+ /* 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");
+
+ if (!(typeSize = H5Tget_size(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ switch (type_class) {
+ case H5T_VLEN: {
+ 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);
+
+ /* Convert each list to a vlen element */
+ for (i = 0; i < (size_t)count; i++) {
+ hvl_t vl_elem;
+
+ if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)in_buf, (jsize)i)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ /* invoke the toArray method */
+ if (mToArray == NULL)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, jList, mToArray);
+ jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array);
+
+ if (jnelmts < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "translate_wbuf: number of VL elements < 0");
+
+ vl_elem.len = (size_t)jnelmts;
+
+ if (NULL == (vl_elem.p = HDmalloc((size_t)jnelmts * vlSize)))
+ H5_OUT_OF_MEMORY_ERROR(ENVONLY, "translate_wbuf: failed to allocate vlen ptr buffer");
+
+ translate_wbuf(ENVONLY, array, memb, vlClass, (jsize)jnelmts, vl_elem.p);
+
+ HDmemcpy(char_buf + i * sizeof(hvl_t), &vl_elem, sizeof(hvl_t));
+
+ ENVPTR->DeleteLocalRef(ENVONLY, jList);
+ } /* end for (i = 0; i < count; i++) */
+ break;
+ } /* H5T_VLEN */
+ case H5T_COMPOUND: {
+ void *objBuf = NULL;
+
+ /* Convert each list to a compound element */
+ for (i = 0; i < (size_t)count; i++) {
+ if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)in_buf, (jsize)i)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ int nmembs = H5Tget_nmembers(mem_type_id);
+
+ /* invoke the toArray method */
+ if (mToArray == NULL)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, jList, mToArray);
+ jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array);
+
+ if (jnelmts != nmembs)
+ H5_BAD_ARGUMENT_ERROR(
+ ENVONLY, "translate_wbuf: number of elements not equal to number of members");
+
+ /* Convert each compound object to an element */
+ for (x = 0; x < (size_t)nmembs; x++) {
+ H5T_class_t memb_vlClass;
+ size_t memb_vlSize;
+ size_t memb_offset;
+
+ if ((memb = H5Tget_member_type(mem_type_id, (unsigned int)x)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((memb_offset = H5Tget_member_offset(mem_type_id, (unsigned int)x)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ if ((memb_vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(memb_vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ jobject arr_obj = ENVPTR->GetObjectArrayElement(ENVONLY, array, x);
+ translate_atomic_wbuf(ENVONLY, arr_obj, memb, memb_vlClass,
+ char_buf + i * typeSize + memb_offset);
+ ENVPTR->DeleteLocalRef(ENVONLY, arr_obj);
+ H5Tclose(memb);
+ }
+
+ ENVPTR->DeleteLocalRef(ENVONLY, jList);
+ } /* end for (i = 0; i < count; i++) */
+ break;
+ } /* H5T_COMPOUND */
+ case H5T_ARRAY: {
+ void *objBuf = NULL;
+
+ if (!(memb = H5Tget_super(mem_type_id)))
+ H5_LIBRARY_ERROR(ENVONLY);
+ if ((vlClass = H5Tget_class(memb)) < 0)
+ H5_LIBRARY_ERROR(ENVONLY);
+ if (!(vlSize = H5Tget_size(memb)))
+ H5_LIBRARY_ERROR(ENVONLY);
+
+ /* Convert each list to an array element */
+ for (i = 0; i < (size_t)count; i++) {
+ if (NULL == (jList = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)in_buf, (jsize)i)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+
+ /* invoke the toArray method */
+ if (mToArray == NULL)
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ jobjectArray array = (jobjectArray)ENVPTR->CallObjectMethod(ENVONLY, jList, mToArray);
+ jsize jnelmts = ENVPTR->GetArrayLength(ENVONLY, array);
+
+ if (jnelmts < 0)
+ H5_BAD_ARGUMENT_ERROR(ENVONLY, "translate_wbuf: number of array elements < 0");
+
+ translate_wbuf(ENVONLY, array, memb, vlClass, (jsize)jnelmts,
+ char_buf + i * vlSize * jnelmts); // objBuf);
+
+ ENVPTR->DeleteLocalRef(ENVONLY, jList);
+ } /* end for (i = 0; i < count; i++) */
+ break;
+ } /* H5T_ARRAY */
+ case H5T_ENUM:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_REFERENCE:
+ case H5T_STRING: {
+ /* Convert each list to an array element */
+ for (i = 0; i < (size_t)count; i++) {
+ if (NULL == (jobj = ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray)in_buf, (jsize)i)))
+ CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
+ translate_atomic_wbuf(ENVONLY, jobj, mem_type_id, type_class, char_buf + i * typeSize);
+ ENVPTR->DeleteLocalRef(ENVONLY, jobj);
+ }
+ break;
+ }
+ default:
+ H5_UNIMPLEMENTED(ENVONLY, "translate_wbuf: invalid class type");
+ break;
+ } /* switch(type_class) */
+
+done:
+
+ return;
+}
+
+#ifdef __cplusplus
+}
+#endif