Files
hdf5/java/test/TestH5D.java
T
Matt Landgithub-actions b58ab3cc1f Fix bad reads of nested cmpd/vlen types in JNI (#6413)
* Fix H5DreadVL failing for pre-allocate cmpd-of-seq dsets

* Fix bad vlen of cmpd with null slot read

* Fix bad cmpd of cmpd read in java

`translate_rbuf`'s H5T_VLEN case had a similar bug where when `found_jList` was set to false due to an entyr in `ret_buf` being null, `ret_buf.add()` would be invoked on an array of objects without the list .add() method. This would occur whenever a read was invoked of a vlen sequence with a null (non-preallocated) entry. The pre-existing tests only tested the pre-allocated cases.

I removed the use of the `found_jList` flag, since it conflated the passing of an unallocated slot with `ret_buf` not being an array. Instead use `ret_buflen == 0` as the check to match the pattern in H5T_INTEGER and other branches.

The test for this fix is testH5Dread_vlen_of_compound_nullslot.

---

`translate_atomic_rebuf` had two issues related to handling of nested compounds. First, it discarded recursive returns, resulting in the construction of empty lists. Secondly, its member offset (`char_buf + i * typeSize + memb_offset`) was incorrect. In this case, `i` was the member index and `memberSize` was the entire cmpd size, so the offset would be erroneously large. It seems like this came from copying of the offset computation from `translate_rbuf`, which had to advance over entire  elements of compound data. This error was duplicated on the write side in `translate_atomic_wbuf`'s H5T_COMPOUND case (h5util.c:4611).

I changed `translate_atomic_rbuf` to capture the resultant object, and dropped the `i * typeSize` term in both routines.
The new test verifying the fix works is `testH5Dread_vlen_of_nested_compound`.

* Add exception checks

* Update NULL checks in translate_wbuf

* Correct potentially bad array length check

* Clang format

* Fix readVL/writeVL crash on malformed buffer

* Committing clang-format changes

* Add bufSize checks to wbuf/rbuf translation

* Remove vlen pre-allocation support

* Harden JNI buffer interface

* Handle opaque types as byte[] and document JNI buffer data model

Opaque elements were grouped with H5T_INTEGER in the nested-type
translation path, which boxed them as Integer/Long and rejected
arbitrary-sized opaque blobs. Treat H5T_OPAQUE like H5T_REFERENCE
(a byte[] per element) in translate_atomic_rbuf, translate_atomic_wbuf,
and h5validate_atomic_wbuf so nested opaque round-trips correctly.

Also add "Buffer data model" header comments on translate_rbuf() and
translate_wbuf() and note the reference/opaque byte[] leaves in the
H5.java javadocv.

* Initialize typeSize to fix -Werror=maybe-uninitialized

typeSize was assigned only inside the vl_data_class branch but read in
a second, separate vl_data_class branch, which gcc -O2 flags as
maybe-uninitialized under -Werror. Initialize it to 0 at declaration in
H5Aread/H5Awrite/H5Dread/H5Dwrite, matching the existing vl_array_len
pattern.

* Port nested cmpd/vlen tests to java/test and sync reference

The legacy java/test tree's JUnit-TestH5D.txt reference listed the new
nested compound/vlen tests, but the corresponding @Test methods existed
only in java/src-jni/test/TestH5D.java. Port the 10 tests and the
writeCompoundOfVlenDataset helper into java/test/TestH5D.java, remove
debug prints, and
regenerate the reference to match the actual JUnit output.

* Support nested vlen/compound datatypes in Java FFM compat layer

The FFM compatibility layer (java/hdf) lacked the vlen/compound read and
write support that the JNI interface gained, so the nested cmpd/vlen tests
ported into java/test (TestH5D) failed and leaked an id.

VLDataConverter now has recursive encodeValue/decodeValue helpers that pack
and unpack any member class (integer, float, fixed/vl string, nested
compound, and VLEN) in the native HDF5 in-memory layout. These are wired
into convertCompoundDatatype, readCompoundDatatype and convertRawDataToArrayList,
and a type-aware convertToHVLAuto handles top-level VLEN-of-compound writes.
Compound reads now reclaim VL memory, and type/count mismatches raise
IllegalArgumentException instead of silently corrupting data.

H5DwriteVL rejects an undersized buffer up front and routes VLEN writes
through convertToHVLAuto. The JUnit-TestH5D reference regains its trailing
blank line to match the actual JUnit output.

* Committing clang-format changes

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-06 09:52:29 -05:00

3228 lines
125 KiB
Java

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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 LICENSE 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.lang.Integer;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemoryLayout.PathElement;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SequenceLayout;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.VarHandle;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import hdf.hdf5lib.H5;
import hdf.hdf5lib.HDF5Constants;
import hdf.hdf5lib.HDFArray;
import hdf.hdf5lib.callbacks.H5D_iterate_cb;
import hdf.hdf5lib.callbacks.H5D_iterate_t;
import hdf.hdf5lib.exceptions.HDF5Exception;
import hdf.hdf5lib.exceptions.HDF5LibraryException;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
public class TestH5D {
@Rule
public TestName testname = new TestName();
private static final String H5_FILE = "testD.h5";
private static final int DIM_X = 4;
private static final int DIM_Y = 6;
private static final int RANK = 2;
long H5fid = HDF5Constants.H5I_INVALID_HID;
long H5faplid = HDF5Constants.H5I_INVALID_HID;
long H5dsid = HDF5Constants.H5I_INVALID_HID;
long H5dtid = HDF5Constants.H5I_INVALID_HID;
long H5did = HDF5Constants.H5I_INVALID_HID;
long H5did0 = HDF5Constants.H5I_INVALID_HID;
long H5dcpl_id = HDF5Constants.H5I_INVALID_HID;
long[] H5dims = {DIM_X, DIM_Y};
// Values for the status of space allocation
enum H5D_space_status {
H5D_SPACE_STATUS_ERROR(-1),
H5D_SPACE_STATUS_NOT_ALLOCATED(0),
H5D_SPACE_STATUS_PART_ALLOCATED(1),
H5D_SPACE_STATUS_ALLOCATED(2);
private int code;
H5D_space_status(int space_status) { this.code = space_status; }
public int getCode() { return this.code; }
}
// Helper class for compound datatype testing
static class TestSensor {
static final int MAXSTRINGSIZE = 32;
static final int INTEGERSIZE = 4;
static final int DOUBLESIZE = 8;
public int serial_no;
public String location;
public double temperature;
public double pressure;
TestSensor(int serial_no, String location, double temperature, double pressure)
{
this.serial_no = serial_no;
this.location = location;
this.temperature = temperature;
this.pressure = pressure;
}
TestSensor(ArrayList data)
{
this.serial_no = (Integer)data.get(0);
this.location = (String)data.get(1);
this.temperature = (Double)data.get(2);
this.pressure = (Double)data.get(3);
}
ArrayList toArrayList()
{
ArrayList data = new ArrayList();
data.add(serial_no);
data.add(location);
data.add(temperature);
data.add(pressure);
return data;
}
static long createMemType() throws HDF5Exception
{
long strtype_id = HDF5Constants.H5I_INVALID_HID;
long memtype_id = HDF5Constants.H5I_INVALID_HID;
try {
strtype_id = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
H5.H5Tset_size(strtype_id, MAXSTRINGSIZE);
memtype_id = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND,
INTEGERSIZE + MAXSTRINGSIZE + DOUBLESIZE + DOUBLESIZE);
H5.H5Tinsert(memtype_id, "Serial number", 0, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tinsert(memtype_id, "Location", INTEGERSIZE, strtype_id);
H5.H5Tinsert(memtype_id, "Temperature", INTEGERSIZE + MAXSTRINGSIZE,
HDF5Constants.H5T_NATIVE_DOUBLE);
H5.H5Tinsert(memtype_id, "Pressure", INTEGERSIZE + MAXSTRINGSIZE + DOUBLESIZE,
HDF5Constants.H5T_NATIVE_DOUBLE);
H5.H5Tclose(strtype_id);
}
catch (Exception e) {
if (strtype_id >= 0)
H5.H5Tclose(strtype_id);
if (memtype_id >= 0)
H5.H5Tclose(memtype_id);
throw e;
}
return memtype_id;
}
}
private final void _deleteFile(String filename)
{
File file = new File(filename);
if (file.exists()) {
try {
file.delete();
}
catch (SecurityException e) {
}
}
}
private final void _createPDataset(long fid, long dsid, String name, long dcpl_val)
{
try {
H5dcpl_id = H5.H5Pcreate(dcpl_val);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Pcreate: " + err);
}
assertTrue("testH5D._createPDataset: H5.H5Pcreate: ", H5dcpl_id >= 0);
// Set the allocation time to "early". This way we can be sure
// that reading from the dataset immediately after creation will
// return the fill value.
try {
H5.H5Pset_alloc_time(H5dcpl_id, HDF5Constants.H5D_ALLOC_TIME_EARLY);
}
catch (Exception e) {
e.printStackTrace();
}
try {
H5did0 = H5.H5Dcreate(fid, name, HDF5Constants.H5T_STD_I32BE, dsid, HDF5Constants.H5P_DEFAULT,
H5dcpl_id, HDF5Constants.H5P_DEFAULT);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Dcreate: " + err);
}
assertTrue("TestH5D._createPDataset.H5Dcreate: ", H5did0 >= 0);
}
private final void _createChunkDataset(long fid, long dsid, String name, long dapl)
{
try {
H5dcpl_id = H5.H5Pcreate(HDF5Constants.H5P_DATASET_CREATE);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Pcreate: " + err);
}
assertTrue("testH5D._createChunkDataset: H5.H5Pcreate: ", H5dcpl_id >= 0);
// Set the chunking.
long[] chunk_dim = {4, 4};
try {
H5.H5Pset_chunk(H5dcpl_id, RANK, chunk_dim);
}
catch (Exception e) {
e.printStackTrace();
}
try {
H5did = H5.H5Dcreate(fid, name, HDF5Constants.H5T_STD_I32BE, dsid, HDF5Constants.H5P_DEFAULT,
H5dcpl_id, dapl);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Dcreate: " + err);
}
assertTrue("TestH5D._createChunkDataset.H5Dcreate: ", H5did >= 0);
}
private final void _createDataset(long fid, long dsid, String name, long dapl)
{
try {
H5did = H5.H5Dcreate(fid, name, HDF5Constants.H5T_STD_I32BE, dsid, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, dapl);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Dcreate: " + err);
}
assertTrue("TestH5D._createDataset.H5Dcreate: ", H5did >= 0);
}
private final void _createVLStrDataset(String name, long dapl)
{
try {
H5dtid = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Tcopy: " + err);
}
assertTrue("TestH5D._createVLStrDataset.H5Tcopy: ", H5dtid >= 0);
try {
H5.H5Tset_size(H5dtid, HDF5Constants.H5T_VARIABLE);
assertTrue("TestH5D._createVLStrDataset.H5Tis_variable_str", H5.H5Tis_variable_str(H5dtid));
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Tset_size: " + err);
}
try {
H5did = H5.H5Dcreate(H5fid, name, H5dtid, H5dsid, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, dapl);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Dcreate: " + err);
}
assertTrue("TestH5D._createVLStrDataset.H5Dcreate: ", H5did >= 0);
}
private final void _closeH5file() throws HDF5LibraryException
{
if (H5dcpl_id >= 0)
try {
H5.H5Pclose(H5dcpl_id);
}
catch (Exception ex) {
}
if (H5did0 >= 0)
try {
H5.H5Dclose(H5did0);
}
catch (Exception ex) {
}
if (H5did >= 0)
try {
H5.H5Dclose(H5did);
}
catch (Exception ex) {
}
if (H5dtid > 0)
try {
H5.H5Tclose(H5dtid);
}
catch (Exception ex) {
}
if (H5dsid > 0)
try {
H5.H5Sclose(H5dsid);
}
catch (Exception ex) {
}
if (H5fid > 0)
try {
H5.H5Fclose(H5fid);
}
catch (Exception ex) {
}
}
private final void _openH5file(String filename, String dsetname, long dapl)
{
try {
H5fid = H5.H5Fopen(filename, HDF5Constants.H5F_ACC_RDONLY, HDF5Constants.H5P_DEFAULT);
}
catch (Throwable err) {
err.printStackTrace();
fail("TestH5D._openH5file: " + err);
}
assertTrue("TestH5D._openH5file: H5.H5Fopen: ", H5fid >= 0);
try {
H5did = H5.H5Dopen(H5fid, dsetname, dapl);
}
catch (Throwable err) {
err.printStackTrace();
fail("TestH5D._openH5file: " + err);
}
assertTrue("TestH5D._openH5file: H5.H5Dopen: ", H5did >= 0);
try {
H5dsid = H5.H5Dget_space(H5did);
}
catch (Throwable err) {
err.printStackTrace();
fail("TestH5D._openH5file: " + err);
}
assertTrue("TestH5D._openH5file: H5.H5Screate_simple: ", H5dsid > 0);
}
@Before
public void createH5file() throws NullPointerException, HDF5Exception
{
assertTrue("H5 open ids is 0", H5.getOpenIDCount() == 0);
System.out.print(testname.getMethodName());
try {
H5faplid = H5.H5Pcreate(HDF5Constants.H5P_FILE_ACCESS);
H5fid = H5.H5Fcreate(H5_FILE, HDF5Constants.H5F_ACC_TRUNC, HDF5Constants.H5P_DEFAULT, H5faplid);
H5dsid = H5.H5Screate_simple(RANK, H5dims, null);
}
catch (Throwable err) {
err.printStackTrace();
fail("TestH5D.createH5file: " + err);
}
assertTrue("TestH5D.createH5file: H5.H5Fcreate: ", H5fid >= 0);
assertTrue("TestH5D.createH5file: H5.H5Screate_simple: ", H5dsid >= 0);
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
}
@After
public void deleteH5file() throws HDF5LibraryException
{
if (H5dcpl_id >= 0)
try {
H5.H5Pclose(H5dcpl_id);
}
catch (Exception ex) {
}
if (H5did0 >= 0)
try {
H5.H5Dclose(H5did0);
}
catch (Exception ex) {
}
if (H5did >= 0)
try {
H5.H5Dclose(H5did);
}
catch (Exception ex) {
}
if (H5dtid > 0)
try {
H5.H5Tclose(H5dtid);
}
catch (Exception ex) {
}
if (H5dsid > 0)
try {
H5.H5Sclose(H5dsid);
}
catch (Exception ex) {
}
if (H5faplid >= 0)
try {
H5.H5Pclose(H5faplid);
}
catch (Exception ex) {
}
if (H5fid > 0)
try {
H5.H5Fclose(H5fid);
}
catch (Exception ex) {
}
_deleteFile(H5_FILE);
System.out.println();
}
@Test
public void testH5Dcreate()
{
long dataset_id = HDF5Constants.H5I_INVALID_HID;
try {
dataset_id =
H5.H5Dcreate(H5fid, "dset", HDF5Constants.H5T_STD_I32BE, H5dsid, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dcreate: " + err);
}
assertTrue(dataset_id >= 0);
// End access to the dataset and release resources used by it.
try {
if (dataset_id >= 0)
H5.H5Dclose(dataset_id);
}
catch (Exception err) {
err.printStackTrace();
}
}
@Test
public void testH5Dcreate_anon()
{
long dataset_id = HDF5Constants.H5I_INVALID_HID;
try {
dataset_id = H5.H5Dcreate_anon(H5fid, HDF5Constants.H5T_STD_I32BE, H5dsid,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dcreate_anon: " + err);
}
assertTrue(dataset_id >= 0);
// End access to the dataset and release resources used by it.
try {
if (dataset_id >= 0)
H5.H5Dclose(dataset_id);
}
catch (Exception err) {
err.printStackTrace();
}
}
@Test
public void testH5Dopen()
{
long dataset_id = HDF5Constants.H5I_INVALID_HID;
_createDataset(H5fid, H5dsid, "dset", HDF5Constants.H5P_DEFAULT);
try {
H5.H5Dclose(H5did);
H5did = HDF5Constants.H5I_INVALID_HID;
dataset_id = H5.H5Dopen(H5fid, "dset", HDF5Constants.H5P_DEFAULT);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dopen: " + err);
}
assertTrue("testH5Dopen: ", dataset_id >= 0);
// End access to the dataset and release resources used by it.
try {
if (dataset_id >= 0)
H5.H5Dclose(dataset_id);
}
catch (Exception err) {
err.printStackTrace();
}
}
@Test
public void testH5Dget_storage_size_empty()
{
long storage_size = 0;
_createDataset(H5fid, H5dsid, "dset", HDF5Constants.H5P_DEFAULT);
try {
storage_size = H5.H5Dget_storage_size(H5did);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dget_storage_size: " + err);
}
assertTrue("testH5Dget_storage_size: ", storage_size == 0);
}
@Test
public void testH5Dget_storage_size()
{
long storage_size = 0;
int[][] dset_data = new int[DIM_X][DIM_Y];
int FILLVAL = 99;
_createDataset(H5fid, H5dsid, "dset", HDF5Constants.H5P_DEFAULT);
// Initialize the dataset.
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++)
dset_data[indx][jndx] = FILLVAL;
try {
if (H5did >= 0)
H5.H5Dwrite(H5did, HDF5Constants.H5T_NATIVE_INT, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, dset_data[0]);
}
catch (Exception e) {
e.printStackTrace();
}
try {
storage_size = H5.H5Dget_storage_size(H5did);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dget_storage_size: " + err);
}
assertTrue("testH5Dget_storage_size: " + storage_size, storage_size == DIM_X * DIM_Y * 4);
}
@Test
public void testH5Dget_access_plist()
{
long dapl_id = HDF5Constants.H5I_INVALID_HID;
long test_dapl_id = HDF5Constants.H5I_INVALID_HID;
int[] mdc_nelmts1 = {0};
int[] mdc_nelmts2 = {0};
long[] rdcc_nelmts1 = {0};
long[] rdcc_nelmts2 = {0};
long[] rdcc_nbytes1 = {0};
long[] rdcc_nbytes2 = {0};
double[] rdcc_w01 = {0};
double[] rdcc_w02 = {0};
try {
test_dapl_id = H5.H5Pcreate(HDF5Constants.H5P_DATASET_ACCESS);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dget_access_plist: H5.H5Pcreate: " + err);
}
assertTrue("testH5Dget_access_plist: test_dapl_id: ", test_dapl_id >= 0);
try {
H5.H5Pget_cache(H5faplid, mdc_nelmts1, rdcc_nelmts1, rdcc_nbytes1, rdcc_w01);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dget_access_plist: H5.H5Pget_cache: " + err);
}
_createChunkDataset(H5fid, H5dsid, "dset", test_dapl_id);
try {
dapl_id = H5.H5Dget_access_plist(H5did);
assertTrue("testH5Dget_access_plist: dapl_id: ", dapl_id >= 0);
H5.H5Pget_chunk_cache(dapl_id, rdcc_nelmts2, rdcc_nbytes2, rdcc_w02);
}
catch (Exception err) {
err.printStackTrace();
fail("testH5Dget_access_plist: H5.H5Dget_access_plist: " + err);
}
// End access to the dataset and release resources used by it.
try {
if (dapl_id >= 0)
H5.H5Pclose(dapl_id);
}
catch (Exception err) {
err.printStackTrace();
}
try {
if (test_dapl_id >= 0)
H5.H5Pclose(test_dapl_id);
}
catch (Exception err) {
err.printStackTrace();
}
assertTrue("testH5Dget_access_plist: ", rdcc_nelmts2 == rdcc_nelmts2 && rdcc_nbytes2 == rdcc_nbytes2);
}
@Test
public void testH5Dget_space_status()
{
int[][] write_dset_data = new int[DIM_X][DIM_Y];
int space_status = -1;
int space_status0 = -1;
// Initialize the dataset.
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++)
write_dset_data[indx][jndx] = indx * jndx - jndx;
_createPDataset(H5fid, H5dsid, "dset0", HDF5Constants.H5P_DATASET_CREATE);
_createDataset(H5fid, H5dsid, "dset", HDF5Constants.H5P_DEFAULT);
// Retrieve and print space status and storage size for dset0.
try {
space_status0 = H5.H5Dget_space_status(H5did0);
}
catch (Exception e) {
e.printStackTrace();
}
assertTrue("testH5Dget_space_status0 - H5.H5Dget_space_status: ",
space_status0 == H5D_space_status.H5D_SPACE_STATUS_ALLOCATED.getCode());
// Retrieve and print space status and storage size for dset.
try {
space_status = H5.H5Dget_space_status(H5did);
}
catch (Exception e) {
e.printStackTrace();
}
assertFalse("testH5Dget_space_status - H5.H5Dget_space_status: ",
space_status == H5D_space_status.H5D_SPACE_STATUS_ALLOCATED.getCode());
// Write the data to the dataset.
try {
H5.H5Dwrite(H5did, HDF5Constants.H5T_NATIVE_INT, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, write_dset_data);
}
catch (Exception e) {
e.printStackTrace();
}
// Retrieve and print space status and storage size for dset.
try {
space_status = H5.H5Dget_space_status(H5did);
}
catch (Exception e) {
e.printStackTrace();
}
assertTrue("testH5Dget_space_status - H5.H5Dget_space_status: ",
space_status == H5D_space_status.H5D_SPACE_STATUS_ALLOCATED.getCode());
}
@Test(expected = HDF5LibraryException.class)
public void testH5Dget_space_closed() throws Throwable
{
long dataset_id = HDF5Constants.H5I_INVALID_HID;
try {
dataset_id =
H5.H5Dcreate(H5fid, "dset", HDF5Constants.H5T_STD_I32BE, H5dsid, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Dcreate: " + err);
}
assertTrue("TestH5D.testH5Dget_space_closed: ", dataset_id >= 0);
H5.H5Dclose(dataset_id);
H5.H5Dget_space(dataset_id);
}
@Test
public void testH5Dget_space()
{
long dataspace_id = HDF5Constants.H5I_INVALID_HID;
_createDataset(H5fid, H5dsid, "dset", HDF5Constants.H5P_DEFAULT);
try {
dataspace_id = H5.H5Dget_space(H5did);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Dget_space: " + err);
}
assertTrue("TestH5D.testH5Dget_space: ", dataspace_id >= 0);
// End access to the dataspace and release resources used by it.
try {
if (dataspace_id >= 0)
H5.H5Sclose(dataspace_id);
}
catch (Exception err) {
err.printStackTrace();
}
}
@Test(expected = HDF5LibraryException.class)
public void testH5Dget_type_closed() throws Throwable
{
long dataset_id = HDF5Constants.H5I_INVALID_HID;
try {
dataset_id =
H5.H5Dcreate(H5fid, "dset", HDF5Constants.H5T_STD_I32BE, H5dsid, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Dcreate: " + err);
}
assertTrue("TestH5D.testH5Dget_type_closed: ", dataset_id >= 0);
H5.H5Dclose(dataset_id);
H5.H5Dget_type(dataset_id);
}
@Test
public void testH5Dget_type()
{
long datatype_id = HDF5Constants.H5I_INVALID_HID;
_createDataset(H5fid, H5dsid, "dset", HDF5Constants.H5P_DEFAULT);
try {
datatype_id = H5.H5Dget_type(H5did);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Dget_type: " + err);
}
assertTrue("TestH5D.testH5Dget_type: ", datatype_id >= 0);
// End access to the datatype and release resources used by it.
try {
if (datatype_id >= 0)
H5.H5Tclose(datatype_id);
}
catch (Exception err) {
err.printStackTrace();
}
}
@Test
public void testH5Dget_offset()
{
int[][] write_dset_data = new int[DIM_X][DIM_Y];
long dset_address = 0;
_createDataset(H5fid, H5dsid, "dset", HDF5Constants.H5P_DEFAULT);
try {
// Test dataset address. Should be undefined.
dset_address = H5.H5Dget_offset(H5did);
}
catch (HDF5LibraryException hdfex) {
;
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Dget_offset: " + err);
}
// Write the data to the dataset.
try {
H5.H5Dwrite(H5did, HDF5Constants.H5T_NATIVE_INT, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, write_dset_data);
}
catch (Exception e) {
e.printStackTrace();
}
try {
// Test dataset address.
dset_address = H5.H5Dget_offset(H5did);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Dget_offset: " + err);
}
assertTrue("TestH5D.testH5Dget_offset: ", dset_address >= 0);
}
@Test
public void testH5Dfill_null()
{
Integer[] buf_data = new Integer[DIM_X * DIM_Y];
// Initialize memory buffer
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++) {
buf_data[(indx * DIM_Y) + jndx] = Integer.valueOf(indx * jndx - jndx);
}
byte[] buf_array = HDFArray.IntegerToByte(buf_data);
// Fill selection in memory
try {
H5.H5Dfill(null, HDF5Constants.H5T_NATIVE_UINT, buf_array, HDF5Constants.H5T_NATIVE_UINT, H5dsid);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Dfill: " + err);
}
buf_data = HDFArray.ByteToInteger(buf_array);
// Verify memory buffer the hard way
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++)
assertTrue("H5.H5Dfill: [" + indx + "," + jndx + "] ",
buf_data[(indx * DIM_Y) + jndx].compareTo(0) == 0);
}
@Test
public void testH5Dfill()
{
Integer[] buf_data = new Integer[DIM_X * DIM_Y];
byte[] fill_value = HDFArray.intToBytes(254);
// Initialize memory buffer
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++) {
buf_data[(indx * DIM_Y) + jndx] = Integer.valueOf(indx * jndx - jndx);
}
byte[] buf_array = HDFArray.IntegerToByte(buf_data);
// Fill selection in memory
try {
H5.H5Dfill(fill_value, HDF5Constants.H5T_NATIVE_UINT, buf_array, HDF5Constants.H5T_NATIVE_UINT,
H5dsid);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Dfill: " + err);
}
buf_data = HDFArray.ByteToInteger(buf_array);
// Verify memory buffer the hard way
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++)
assertTrue("H5.H5Dfill: [" + indx + "," + jndx + "] ",
buf_data[(indx * DIM_Y) + jndx].compareTo(254) == 0);
}
@Ignore
public void testH5Diterate()
{
final int SPACE_RANK = 2;
final int SPACE_FILL = 254;
MemoryLayout ITER_LAYOUT = MemoryLayout.structLayout(
MemoryLayout.sequenceLayout(SPACE_RANK, ValueLayout.JAVA_LONG).withName("fill_coords"),
ValueLayout.JAVA_LONG.withName("fill_curr_coord"), ValueLayout.JAVA_INT.withName("fill_value"));
VarHandle coordsHandle = ITER_LAYOUT.arrayElementVarHandle(PathElement.groupElement("fill_coords"),
PathElement.sequenceElement());
VarHandle curr_coordHandle = ITER_LAYOUT.varHandle(PathElement.groupElement("fill_curr_coord"));
VarHandle valueHandle = ITER_LAYOUT.varHandle(PathElement.groupElement("fill_value"));
class H5D_iter_data implements H5D_iterate_t {
public long[] fill_coords; /* Pointer to selection's coordinates */
public long fill_curr_coord; /* Current coordinate to examine */
public int fill_value; /* The fill value to check */
}
H5D_iterate_t iter_data = new H5D_iter_data();
class H5D_iter_callback implements H5D_iterate_cb {
public int apply(MemorySegment elem, long type_id, int ndim, MemorySegment point,
MemorySegment operator_data)
{
// Check value in current buffer location
int element = elem.get(ValueLayout.JAVA_INT, 0);
// System.out.println("element = " + element + " fill_value = " +
// (int)valueHandle.get(operator_data, 0));
if (element != (int)valueHandle.get(operator_data, 0))
return -1;
// Check number of dimensions
if (ndim != SPACE_RANK)
return (-1);
// Check Coordinates
long[] fill_coords = new long[ndim];
long fill_curr_coord = (long)curr_coordHandle.get(operator_data, 0);
for (int i = 0; i < ndim; i++)
fill_coords[i] = (long)coordsHandle.get(operator_data, 0L, 2 * fill_curr_coord + i);
fill_curr_coord++;
curr_coordHandle.set(operator_data, 0, fill_curr_coord);
for (int i = 0; i < ndim; i++)
if (fill_coords[i] != point.get(ValueLayout.JAVA_LONG, i))
return (-1);
return (0);
}
}
Integer[] buf_data = new Integer[DIM_X * DIM_Y];
byte[] fill_value = HDFArray.intToBytes(SPACE_FILL);
// Initialize memory buffer
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++) {
buf_data[(indx * DIM_Y) + jndx] = Integer.valueOf(indx * jndx - jndx);
}
byte[] buf_array = HDFArray.IntegerToByte(buf_data);
// Fill selection in memory
try {
H5.H5Dfill(fill_value, HDF5Constants.H5T_NATIVE_UINT, buf_array, HDF5Constants.H5T_NATIVE_UINT,
H5dsid);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Diterate: " + err);
}
// Initialize the iterator structure
((H5D_iter_data)iter_data).fill_value = SPACE_FILL;
((H5D_iter_data)iter_data).fill_curr_coord = 0;
// Set the coordinates of the selection
((H5D_iter_data)iter_data).fill_coords =
new long[DIM_X * DIM_Y * SPACE_RANK]; /* Coordinates of selection */
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++) {
((H5D_iter_data)iter_data).fill_coords[2 * (indx * DIM_Y + jndx)] = indx;
((H5D_iter_data)iter_data).fill_coords[2 * (indx * DIM_Y + jndx) + 1] = jndx;
} /* end for */
// Iterate through selection, verifying correct data
H5D_iterate_cb iter_cb = new H5D_iter_callback();
int op_status = -1;
try {
op_status = H5.H5Diterate(buf_array, HDF5Constants.H5T_NATIVE_UINT, H5dsid, iter_cb, iter_data);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Diterate: " + err);
}
assertTrue("H5Diterate ", op_status == 0);
}
@Ignore
public void testH5Diterate_write()
{
final int SPACE_RANK = 2;
final int SPACE_FILL = 254;
MemoryLayout ITER_LAYOUT = MemoryLayout.structLayout(
MemoryLayout.sequenceLayout(SPACE_RANK, ValueLayout.JAVA_LONG).withName("fill_coords"),
ValueLayout.JAVA_LONG.withName("fill_curr_coord"), ValueLayout.JAVA_INT.withName("fill_value"));
VarHandle coordsHandle = ITER_LAYOUT.arrayElementVarHandle(PathElement.groupElement("fill_coords"),
PathElement.sequenceElement());
VarHandle curr_coordHandle = ITER_LAYOUT.varHandle(PathElement.groupElement("fill_curr_coord"));
VarHandle valueHandle = ITER_LAYOUT.varHandle(PathElement.groupElement("fill_value"));
class H5D_iter_data implements H5D_iterate_t {
public long[] fill_coords; /* Pointer to selection's coordinates */
public long fill_curr_coord; /* Current coordinate to examine */
public int fill_value; /* The fill value to check */
}
H5D_iterate_t iter_data = new H5D_iter_data();
class H5D_iter_callback implements H5D_iterate_cb {
public int apply(MemorySegment elem, long type_id, int ndim, MemorySegment point,
MemorySegment operator_data)
{
// Check value in current buffer location
int element = elem.get(ValueLayout.JAVA_INT, 0);
if (element != (int)valueHandle.get(operator_data, 0))
return -1;
// Check number of dimensions
if (ndim != SPACE_RANK)
return (-1);
// Check Coordinates
long[] fill_coords = new long[ndim];
long fill_curr_coord = (long)curr_coordHandle.get(operator_data, 0);
for (int i = 0; i < ndim; i++)
fill_coords[i] = (long)coordsHandle.get(operator_data, 0L, 2 * fill_curr_coord + i);
fill_curr_coord++;
curr_coordHandle.set(operator_data, 0, fill_curr_coord);
for (int i = 0; i < ndim; i++)
if (fill_coords[i] != point.get(ValueLayout.JAVA_LONG, i))
return (-1);
element -= 128;
elem.set(ValueLayout.JAVA_LONG, 0, element);
return (0);
}
}
Integer[] buf_data = new Integer[DIM_X * DIM_Y];
byte[] fill_value = new byte[4];
ByteBuffer.wrap(fill_value).putInt(SPACE_FILL);
// Initialize memory buffer
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++) {
buf_data[(indx * DIM_Y) + jndx] = Integer.valueOf(indx * jndx - jndx);
}
byte[] buf_array = HDFArray.IntegerToByte(buf_data);
// Fill selection in memory
try {
H5.H5Dfill(fill_value, HDF5Constants.H5T_NATIVE_UINT, buf_array, HDF5Constants.H5T_NATIVE_UINT,
H5dsid);
}
catch (Exception err) {
err.printStackTrace();
fail("H5.H5Diterate: " + err);
}
// Initialize the iterator structure
((H5D_iter_data)iter_data).fill_value = SPACE_FILL;
((H5D_iter_data)iter_data).fill_curr_coord = 0;
// Set the coordinates of the selection
((H5D_iter_data)iter_data).fill_coords =
new long[DIM_X * DIM_Y * SPACE_RANK]; /* Coordinates of selection */
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++) {
((H5D_iter_data)iter_data).fill_coords[2 * (indx * DIM_Y + jndx)] = indx;
((H5D_iter_data)iter_data).fill_coords[2 * (indx * DIM_Y + jndx) + 1] = jndx;
} /* end for */
// Iterate through selection, verifying correct data
H5D_iterate_cb iter_cb = new H5D_iter_callback();
int op_status = -1;
try {
op_status = H5.H5Diterate(buf_array, HDF5Constants.H5T_NATIVE_UINT, H5dsid, iter_cb, iter_data);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.H5Diterate: " + err);
}
assertTrue("H5Diterate ", op_status == 0);
buf_data = HDFArray.ByteToInteger(buf_array);
// Verify memory buffer the hard way
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++)
assertTrue("H5.H5Diterate: [" + indx + "," + jndx + "] " + buf_data[(indx * DIM_Y) + jndx],
buf_data[(indx * DIM_Y) + jndx].compareTo(126) == 0);
}
@Test
public void testH5Dvlen_get_buf_size()
{
String[] str_data = {"Parting", "is such", "sweet", "sorrow.", "Testing", "one", "two", "three.",
"Dog,", "man's", "best", "friend.", "Diamonds", "are", "a", "girls!",
"S A", "T U R", "D A Y", "night", "That's", "all", "folks", "!!!"};
long vl_size = -1; /* Number of bytes used */
long str_data_bytes = 0;
for (int idx = 0; idx < str_data.length; idx++)
str_data_bytes += str_data[idx].length() + 1; // Account for terminating null
// Convert String[] to ArrayList[] format for VL data
ArrayList[] vl_str_data = new ArrayList[str_data.length];
for (int i = 0; i < str_data.length; i++) {
vl_str_data[i] = new ArrayList<>();
vl_str_data[i].add(str_data[i]);
}
_createVLStrDataset("dset", HDF5Constants.H5P_DEFAULT);
try {
if ((H5did >= 0) && (H5dtid >= 0))
H5.H5DwriteVL(H5did, H5dtid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_str_data);
}
catch (Exception e) {
e.printStackTrace();
}
try {
vl_size = H5.H5Dvlen_get_buf_size(H5did, H5dtid, H5dsid);
}
catch (Exception e) {
e.printStackTrace();
}
assertTrue("H5Dvlen_get_buf_size " + vl_size + " == " + str_data_bytes, vl_size == str_data_bytes);
}
@Test
// ISSUE: Triple-nested VL type (VL of VL of VL-String) - crashes in H5T__vlen_reclaim
// This test uses H5Tvlen_create(H5T_VARIABLE_STRING) creating VL<VL<Variable-Length-String>>
// Note: Nested VL<VL<Integer>> works (see testH5DVLwrVL), but VL<VL<VL-String>> crashes during H5Treclaim
// Simple VL strings work (testH5Dvlen_write_read), double-nested VL works (testH5DVLwrVL)
// This is the most complex VL case with three levels of variable sizing
@Ignore("DISABLED: Triple-nested VL type (VL of VL of VL-String) crashes in H5T__vlen_reclaim during "
+ "memory cleanup")
public void
testH5Dvlen_string_buffer() throws Throwable
{
String dset_str_name = "VLStringdata";
long dset_str_id = HDF5Constants.H5I_INVALID_HID;
long dtype_str_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {64};
long lsize = 1;
String[] str_data0 = {"Parting", "is such", "sweet", "sorrow."};
String[] str_data1 = {"Testing", "one", "two", "three."};
String[] str_data2 = {"Dog,", "man's", "best", "friend."};
String[] str_data3 = {"Diamonds", "are", "a", "girls!"};
String[] str_data4 = {"S A", "T U R", "D A Y", "night"};
String[] str_data5 = {"That's", "all", "folks", "!!!"};
ArrayList[] vl_str_data = new ArrayList[6];
vl_str_data[0] = new ArrayList<String>(Arrays.asList(str_data0));
vl_str_data[1] = new ArrayList<String>(Arrays.asList(str_data1));
vl_str_data[2] = new ArrayList<String>(Arrays.asList(str_data2));
vl_str_data[3] = new ArrayList<String>(Arrays.asList(str_data3));
vl_str_data[4] = new ArrayList<String>(Arrays.asList(str_data4));
vl_str_data[5] = new ArrayList<String>(Arrays.asList(str_data5));
try {
H5dtid = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5Dvlen_string_buffer.H5.H5Tcopy: " + err);
}
assertTrue("testH5Dvlen_string_buffer.H5Tcopy: ", H5dtid >= 0);
try {
H5.H5Tset_size(H5dtid, HDF5Constants.H5T_VARIABLE);
assertTrue("testH5Dvlen_string_buffer.H5Tis_variable_str", H5.H5Tis_variable_str(H5dtid));
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5Dvlen_string_buffer.H5Tset_size: " + err);
}
try {
dtype_str_id = H5.H5Tvlen_create(H5dtid);
assertTrue("testH5Dvlen_string_buffer.H5Tvlen_create: ", dtype_str_id >= 0);
}
catch (Exception err) {
if (dtype_str_id > 0)
try {
H5.H5Tclose(dtype_str_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("testH5Dvlen_string_buffer: " + err);
}
try {
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue(dspace_id > 0);
dset_str_id =
H5.H5Dcreate(H5fid, dset_str_name, dtype_str_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5Dvlen_string_buffer: ", dset_str_id >= 0);
H5.H5DwriteVL(dset_str_id, dtype_str_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_str_data);
}
catch (Exception err) {
if (dset_str_id > 0)
try {
H5.H5Dclose(dset_str_id);
}
catch (Exception ex) {
}
if (dtype_str_id > 0)
try {
H5.H5Tclose(dtype_str_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("testH5Dvlen_string_buffer: " + err);
}
finally {
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
for (int j = 0; j < dims.length; j++)
lsize *= dims[j];
ArrayList[] vl_readbuf = new ArrayList[4];
for (int j = 0; j < lsize; j++)
vl_readbuf[j] = new ArrayList<String>();
try {
H5.H5DreadVL(dset_str_id, dtype_str_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_readbuf);
}
catch (Exception ex) {
ex.printStackTrace();
}
assertTrue("testH5Dvlen_string_buffer:" + vl_readbuf[0].get(0),
vl_str_data[0].get(0).equals(vl_readbuf[0].get(0)));
assertTrue("testH5Dvlen_string_buffer:" + vl_readbuf[1].get(0),
vl_str_data[1].get(0).equals(vl_readbuf[1].get(0)));
assertTrue("testH5Dvlen_string_buffer:" + vl_readbuf[2].get(0),
vl_str_data[2].get(0).equals(vl_readbuf[2].get(0)));
assertTrue("testH5Dvlen_string_buffer:" + vl_readbuf[3].get(0),
vl_str_data[3].get(0).equals(vl_readbuf[3].get(0)));
}
@Test
public void testH5Dvlen_write_read()
{
String[] str_wdata = {"Parting", "is such", "sweet", "sorrow.", "Testing", "one", "two", "three.",
"Dog,", "man's", "best", "friend.", "Diamonds", "are", "a", "girls!",
"S A", "T U R", "D A Y", "night", "That's", "all", "folks", "!!!"};
// Convert String[] to ArrayList[] format for VL data
ArrayList[] vl_wdata = new ArrayList[str_wdata.length];
for (int i = 0; i < str_wdata.length; i++) {
vl_wdata[i] = new ArrayList<>();
vl_wdata[i].add(str_wdata[i]);
}
ArrayList[] vl_rdata = new ArrayList[DIM_X * DIM_Y];
for (int j = 0; j < vl_rdata.length; j++)
vl_rdata[j] = new ArrayList<String>();
_createVLStrDataset("dset", HDF5Constants.H5P_DEFAULT);
try {
if ((H5did >= 0) && (H5dtid >= 0))
H5.H5DwriteVL(H5did, H5dtid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_wdata);
}
catch (Exception e) {
e.printStackTrace();
}
try {
if ((H5did >= 0) && (H5dtid >= 0))
H5.H5DreadVL(H5did, H5dtid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_rdata);
}
catch (Exception e) {
e.printStackTrace();
}
for (int v = 0; v < DIM_X * DIM_Y; v++)
assertTrue("testH5Dvlen_write_read " + str_wdata[v] + " == " + vl_rdata[v].get(0),
str_wdata[v].equals(vl_rdata[v].get(0)));
}
@Test
public void testH5DVLwr()
{
String dset_int_name = "VLIntdata";
String dset_dbl_name = "VLDbldata";
long dset_int_id = HDF5Constants.H5I_INVALID_HID;
long dset_dbl_id = HDF5Constants.H5I_INVALID_HID;
long dtype_int_id = HDF5Constants.H5I_INVALID_HID;
long dtype_dbl_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {4};
long lsize = 1;
ArrayList[] vl_int_data = new ArrayList[4];
ArrayList[] vl_dbl_data = new ArrayList[4];
try {
// Write Integer data
vl_int_data[0] = new ArrayList<Integer>(Arrays.asList(1));
vl_int_data[1] = new ArrayList<Integer>(Arrays.asList(2, 3));
vl_int_data[2] = new ArrayList<Integer>(Arrays.asList(4, 5, 6));
vl_int_data[3] = new ArrayList<Integer>(Arrays.asList(7, 8, 9, 10));
Class dataClass = vl_int_data.getClass();
assertTrue("testH5DVLwr.getClass: " + dataClass, dataClass.isArray());
try {
dtype_int_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_U32LE);
assertTrue("testH5DVLwr.H5Tvlen_create: ", dtype_int_id >= 0);
}
catch (Exception err) {
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DVLwr: " + err);
}
try {
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue(dspace_id > 0);
dset_int_id =
H5.H5Dcreate(H5fid, dset_int_name, dtype_int_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DVLwr: ", dset_int_id >= 0);
H5.H5DwriteVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_int_data);
}
catch (Exception err) {
if (dset_int_id > 0)
try {
H5.H5Dclose(dset_int_id);
}
catch (Exception ex) {
}
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DVLwr: " + err);
}
finally {
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
// Write Double data
vl_dbl_data[0] = new ArrayList<Double>(Arrays.asList(1.1));
vl_dbl_data[1] = new ArrayList<Double>(Arrays.asList(2.2, 3.3));
vl_dbl_data[2] = new ArrayList<Double>(Arrays.asList(4.4, 5.5, 6.6));
vl_dbl_data[3] = new ArrayList<Double>(Arrays.asList(7.7, 8.8, 9.9, 10.0));
dataClass = vl_dbl_data.getClass();
assertTrue("testH5DVLwr.getClass: " + dataClass, dataClass.isArray());
try {
dtype_dbl_id = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_DOUBLE);
assertTrue("testH5DVLwr.H5Tvlen_create: ", dtype_dbl_id >= 0);
}
catch (Exception err) {
if (dtype_dbl_id > 0)
try {
H5.H5Tclose(dtype_dbl_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DVLwr: " + err);
}
try {
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue(dspace_id > 0);
dset_dbl_id =
H5.H5Dcreate(H5fid, dset_dbl_name, dtype_dbl_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DVLwr: ", dset_dbl_id >= 0);
H5.H5DwriteVL(dset_dbl_id, dtype_dbl_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_dbl_data);
}
catch (Exception err) {
if (dset_dbl_id > 0)
try {
H5.H5Dclose(dset_dbl_id);
}
catch (Exception ex) {
}
if (dtype_dbl_id > 0)
try {
H5.H5Tclose(dtype_dbl_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DVLwr: " + err);
}
finally {
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
for (int j = 0; j < dims.length; j++)
lsize *= dims[j];
// Read Integer data
ArrayList[] vl_int_readbuf = new ArrayList[4];
for (int j = 0; j < lsize; j++)
vl_int_readbuf[j] = new ArrayList<Integer>();
try {
H5.H5DreadVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_int_readbuf);
}
catch (Exception ex) {
ex.printStackTrace();
}
assertTrue("testH5DVLwr:" + vl_int_readbuf[0].get(0),
vl_int_data[0].get(0).equals(vl_int_readbuf[0].get(0)));
assertTrue("testH5DVLwr:" + vl_int_readbuf[1].get(0),
vl_int_data[1].get(0).equals(vl_int_readbuf[1].get(0)));
assertTrue("testH5DVLwr:" + vl_int_readbuf[2].get(0),
vl_int_data[2].get(0).equals(vl_int_readbuf[2].get(0)));
assertTrue("testH5DVLwr:" + vl_int_readbuf[3].get(0),
vl_int_data[3].get(0).equals(vl_int_readbuf[3].get(0)));
// Read Double data
ArrayList[] vl_dbl_readbuf = new ArrayList[4];
for (int j = 0; j < lsize; j++)
vl_dbl_readbuf[j] = new ArrayList<Double>();
try {
H5.H5DreadVL(dset_dbl_id, dtype_dbl_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, vl_dbl_readbuf);
}
catch (Exception ex) {
ex.printStackTrace();
}
assertTrue("testH5DVLwr:" + vl_dbl_readbuf[0].get(0),
vl_dbl_data[0].get(0).equals(vl_dbl_readbuf[0].get(0)));
assertTrue("testH5DVLwr:" + vl_dbl_readbuf[1].get(0),
vl_dbl_data[1].get(0).equals(vl_dbl_readbuf[1].get(0)));
assertTrue("testH5DVLwr:" + vl_dbl_readbuf[2].get(0),
vl_dbl_data[2].get(0).equals(vl_dbl_readbuf[2].get(0)));
assertTrue("testH5DVLwr:" + vl_dbl_readbuf[3].get(0),
vl_dbl_data[3].get(0).equals(vl_dbl_readbuf[3].get(0)));
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.testH5DVLwr: " + err);
}
finally {
if (dset_dbl_id > 0)
try {
H5.H5Dclose(dset_dbl_id);
}
catch (Exception ex) {
}
if (dset_int_id > 0)
try {
H5.H5Dclose(dset_int_id);
}
catch (Exception ex) {
}
if (dtype_dbl_id > 0)
try {
H5.H5Tclose(dtype_dbl_id);
}
catch (Exception ex) {
}
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
}
}
@Test
public void testH5DVLwrVL()
{
String dset_int_name = "VLIntdata";
long dset_int_id = HDF5Constants.H5I_INVALID_HID;
long dtype_int_id = HDF5Constants.H5I_INVALID_HID;
long base_dtype_int_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {4};
long lsize = 1;
ArrayList[] base_vl_int_data = new ArrayList[4];
ArrayList[] vl_int_data = new ArrayList[4];
try {
// Write Integer data
vl_int_data[0] = new ArrayList<Integer>(Arrays.asList(1));
vl_int_data[1] = new ArrayList<Integer>(Arrays.asList(2, 3));
vl_int_data[2] = new ArrayList<Integer>(Arrays.asList(4, 5, 6));
vl_int_data[3] = new ArrayList<Integer>(Arrays.asList(7, 8, 9, 10));
Class dataClass = vl_int_data.getClass();
assertTrue("testH5DVLwrVL.getClass: " + dataClass, dataClass.isArray());
// Write VL data
base_vl_int_data[0] = new ArrayList<ArrayList<Integer>>();
base_vl_int_data[0].add(vl_int_data[0]);
base_vl_int_data[1] = new ArrayList<ArrayList<Integer>>();
base_vl_int_data[1].add(vl_int_data[0]);
base_vl_int_data[1].add(vl_int_data[1]);
base_vl_int_data[2] = new ArrayList<ArrayList<Integer>>();
base_vl_int_data[2].add(vl_int_data[0]);
base_vl_int_data[2].add(vl_int_data[1]);
base_vl_int_data[2].add(vl_int_data[2]);
base_vl_int_data[3] = new ArrayList<ArrayList<Integer>>();
base_vl_int_data[3].add(vl_int_data[0]);
base_vl_int_data[3].add(vl_int_data[1]);
base_vl_int_data[3].add(vl_int_data[2]);
base_vl_int_data[3].add(vl_int_data[3]);
try {
dtype_int_id = H5.H5Tvlen_create(HDF5Constants.H5T_STD_U32LE);
assertTrue("testH5DVLwrVL.H5Tvlen_create: ", dtype_int_id >= 0);
base_dtype_int_id = H5.H5Tvlen_create(dtype_int_id);
assertTrue("testH5DVLwrVL.H5Tvlen_create: ", base_dtype_int_id >= 0);
}
catch (Exception err) {
if (base_dtype_int_id > 0)
try {
H5.H5Tclose(base_dtype_int_id);
}
catch (Exception ex) {
}
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DVLwrVL: " + err);
}
try {
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue(dspace_id > 0);
dset_int_id = H5.H5Dcreate(H5fid, dset_int_name, base_dtype_int_id, dspace_id,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DVLwrVL: ", dset_int_id >= 0);
H5.H5DwriteVL(dset_int_id, base_dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, base_vl_int_data);
}
catch (Exception err) {
if (dset_int_id > 0)
try {
H5.H5Dclose(dset_int_id);
}
catch (Exception ex) {
}
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DVLwrVL: " + err);
}
finally {
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
for (int j = 0; j < dims.length; j++)
lsize *= dims[j];
// Read Integer data
ArrayList[] base_vl_readbuf = new ArrayList[4];
for (int j = 0; j < lsize; j++)
base_vl_readbuf[j] = new ArrayList<ArrayList<Integer>>();
try {
H5.H5DreadVL(dset_int_id, base_dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, base_vl_readbuf);
}
catch (Exception ex) {
ex.printStackTrace();
}
ArrayList<ArrayList<Integer>> vl_readbuf = (ArrayList<ArrayList<Integer>>)base_vl_readbuf[0];
assertTrue("vl_readbuf 0 exists", vl_readbuf != null);
ArrayList<Integer> vl_readbuf_int = (ArrayList<Integer>)(vl_readbuf.get(0));
/*
* System.out.println(); System.out.println("vl_readbuf: " + vl_readbuf);
* System.out.println("vl_readbuf_int: " + vl_readbuf_int);
*/
assertTrue("testH5DVLwrVL:" + vl_readbuf_int.get(0),
vl_int_data[0].get(0).equals(vl_readbuf_int.get(0)));
vl_readbuf = (ArrayList<ArrayList<Integer>>)base_vl_readbuf[1];
vl_readbuf_int = (ArrayList<Integer>)(vl_readbuf.get(1));
/*
* System.out.println("vl_readbuf: " + vl_readbuf); System.out.println("vl_readbuf_int: " +
* vl_readbuf_int);
*/
assertTrue("testH5DVLwrVL:" + vl_readbuf_int.get(1),
vl_int_data[1].get(1).equals(vl_readbuf_int.get(1)));
vl_readbuf = (ArrayList<ArrayList<Integer>>)base_vl_readbuf[2];
vl_readbuf_int = (ArrayList<Integer>)(vl_readbuf.get(2));
/*
* System.out.println("vl_readbuf: " + vl_readbuf); System.out.println("vl_readbuf_int: " +
* vl_readbuf_int);
*/
assertTrue("testH5DVLwrVL:" + vl_readbuf_int.get(2),
vl_int_data[2].get(2).equals(vl_readbuf_int.get(2)));
vl_readbuf = (ArrayList<ArrayList<Integer>>)base_vl_readbuf[3];
vl_readbuf_int = (ArrayList<Integer>)(vl_readbuf.get(3));
/*
* System.out.println("vl_readbuf: " + vl_readbuf); System.out.println("vl_readbuf_int: " +
* vl_readbuf_int);
*/
assertTrue("testH5DVLwrVL:" + vl_readbuf_int.get(3),
vl_int_data[3].get(3).equals(vl_readbuf_int.get(3)));
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.testH5DVLwrVL: " + err);
}
finally {
if (dset_int_id > 0)
try {
H5.H5Dclose(dset_int_id);
}
catch (Exception ex) {
}
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
if (base_dtype_int_id > 0)
try {
H5.H5Tclose(base_dtype_int_id);
}
catch (Exception ex) {
}
}
}
@Test
public void testH5DArraywr()
{
String dset_int_name = "ArrayIntdata";
long dset_int_id = HDF5Constants.H5I_INVALID_HID;
long dtype_int_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {4};
long lsize = 1;
ArrayList[] arr_int_data = new ArrayList[4];
try {
// Write Integer data
arr_int_data[0] = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4));
arr_int_data[1] = new ArrayList<Integer>(Arrays.asList(2, 3, 4, 5));
arr_int_data[2] = new ArrayList<Integer>(Arrays.asList(4, 5, 6, 7));
arr_int_data[3] = new ArrayList<Integer>(Arrays.asList(7, 8, 9, 10));
Class dataClass = arr_int_data.getClass();
assertTrue("testH5DArraywr.getClass: " + dataClass, dataClass.isArray());
try {
dtype_int_id = H5.H5Tarray_create(HDF5Constants.H5T_STD_U32LE, 1, dims);
assertTrue("testH5DArraywr.H5Tarray_create: ", dtype_int_id >= 0);
}
catch (Exception err) {
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DArraywr: " + err);
}
try {
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue(dspace_id > 0);
dset_int_id =
H5.H5Dcreate(H5fid, dset_int_name, dtype_int_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DVLwr: ", dset_int_id >= 0);
H5.H5DwriteVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, arr_int_data);
}
catch (Exception err) {
if (dset_int_id > 0)
try {
H5.H5Dclose(dset_int_id);
}
catch (Exception ex) {
}
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DVLwr: " + err);
}
finally {
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
for (int j = 0; j < dims.length; j++)
lsize *= dims[j];
// Read Integer data
ArrayList[] arr_readbuf = new ArrayList[4];
for (int j = 0; j < lsize; j++)
arr_readbuf[j] = new ArrayList<Integer>();
try {
H5.H5DreadVL(dset_int_id, dtype_int_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, arr_readbuf);
}
catch (Exception ex) {
ex.printStackTrace();
}
assertTrue("testH5DVLwr:" + arr_readbuf[0].get(0),
arr_int_data[0].get(0).equals(arr_readbuf[0].get(0)));
assertTrue("testH5DVLwr:" + arr_readbuf[1].get(0),
arr_int_data[1].get(0).equals(arr_readbuf[1].get(0)));
assertTrue("testH5DVLwr:" + arr_readbuf[2].get(0),
arr_int_data[2].get(0).equals(arr_readbuf[2].get(0)));
assertTrue("testH5DVLwr:" + arr_readbuf[3].get(0),
arr_int_data[3].get(0).equals(arr_readbuf[3].get(0)));
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.testH5DArraywr: " + err);
}
finally {
if (dset_int_id > 0)
try {
H5.H5Dclose(dset_int_id);
}
catch (Exception ex) {
}
if (dtype_int_id > 0)
try {
H5.H5Tclose(dtype_int_id);
}
catch (Exception ex) {
}
}
}
@Test
public void testH5DArray_string_buffer() throws Throwable
{
String dset_str_name = "ArrayStringdata";
long dset_str_id = HDF5Constants.H5I_INVALID_HID;
long dtype_str_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] strdims = {4};
long[] dims = {6};
long lsize = 1;
String[] str_data0 = {"Parting", "is such", "sweet", "sorrow."};
String[] str_data1 = {"Testing", "one", "two", "three."};
String[] str_data2 = {"Dog,", "man's", "best", "friend."};
String[] str_data3 = {"Diamonds", "are", "a", "girls!"};
String[] str_data4 = {"S A", "T U R", "D A Y", "night"};
String[] str_data5 = {"That's", "all", "folks", "!!!"};
ArrayList[] arr_str_data = new ArrayList[6];
arr_str_data[0] = new ArrayList<String>(Arrays.asList(str_data0));
arr_str_data[1] = new ArrayList<String>(Arrays.asList(str_data1));
arr_str_data[2] = new ArrayList<String>(Arrays.asList(str_data2));
arr_str_data[3] = new ArrayList<String>(Arrays.asList(str_data3));
arr_str_data[4] = new ArrayList<String>(Arrays.asList(str_data4));
arr_str_data[5] = new ArrayList<String>(Arrays.asList(str_data5));
try {
H5dtid = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5DArray_string_buffer.H5.H5Tcopy: " + err);
}
assertTrue("testH5DArray_string_buffer.H5Tcopy: ", H5dtid >= 0);
try {
H5.H5Tset_size(H5dtid, HDF5Constants.H5T_VARIABLE);
assertTrue("testH5DArray_string_buffer.H5Tis_variable_str", H5.H5Tis_variable_str(H5dtid));
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5DArray_string_buffer.H5Tset_size: " + err);
}
try {
dtype_str_id = H5.H5Tarray_create(H5dtid, 1, strdims);
assertTrue("testH5DArray_string_buffer.H5Tarray_create: ", dtype_str_id >= 0);
}
catch (Exception err) {
if (dtype_str_id > 0)
try {
H5.H5Tclose(dtype_str_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("testH5DArray_string_buffer: " + err);
}
try {
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue(dspace_id > 0);
dset_str_id =
H5.H5Dcreate(H5fid, dset_str_name, dtype_str_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DArray_string_buffer: ", dset_str_id >= 0);
H5.H5DwriteVL(dset_str_id, dtype_str_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, arr_str_data);
}
catch (Exception err) {
if (dset_str_id > 0)
try {
H5.H5Dclose(dset_str_id);
}
catch (Exception ex) {
}
if (dtype_str_id > 0)
try {
H5.H5Tclose(dtype_str_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("testH5DArray_string_buffer: " + err);
}
finally {
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
for (int j = 0; j < dims.length; j++)
lsize *= dims[j];
ArrayList[] arr_readbuf = new ArrayList[6];
for (int j = 0; j < lsize; j++)
arr_readbuf[j] = new ArrayList<String>();
try {
H5.H5DreadVL(dset_str_id, dtype_str_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, arr_readbuf);
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
if (dset_str_id > 0)
try {
H5.H5Dclose(dset_str_id);
}
catch (Exception ex) {
}
if (dtype_str_id > 0)
try {
H5.H5Tclose(dtype_str_id);
}
catch (Exception ex) {
}
}
assertTrue("testH5DArray_string_buffer:" + arr_readbuf[0].get(0),
arr_str_data[0].get(0).equals(arr_readbuf[0].get(0)));
assertTrue("testH5DArray_string_buffer:" + arr_readbuf[1].get(0),
arr_str_data[1].get(0).equals(arr_readbuf[1].get(0)));
assertTrue("testH5DArray_string_buffer:" + arr_readbuf[2].get(0),
arr_str_data[2].get(0).equals(arr_readbuf[2].get(0)));
assertTrue("testH5DArray_string_buffer:" + arr_readbuf[3].get(0),
arr_str_data[3].get(0).equals(arr_readbuf[3].get(0)));
}
@Test
public void testH5DArrayenum_rw()
{
String dset_enum_name = "ArrayEnumdata";
long dset_enum_id = HDF5Constants.H5I_INVALID_HID;
long dtype_enum_id = HDF5Constants.H5I_INVALID_HID;
long dtype_arr_enum_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {4};
long lsize = 1;
String enum_type = "Enum_type";
byte[] enum_val = new byte[4];
String enum_name = null;
// Create a enumerate datatype
try {
dtype_enum_id = H5.H5Tcreate(HDF5Constants.H5T_ENUM, (long)1);
assertTrue("testH5DArrayenum_wr.H5Tarray_create: ", dtype_enum_id >= 0);
}
catch (Throwable err) {
if (dtype_enum_id > 0)
try {
H5.H5Tclose(dtype_enum_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("testH5DArrayenum_rw:H5Tcreate " + err);
}
try {
enum_val[0] = 10;
H5.H5Tenum_insert(dtype_enum_id, "RED", enum_val);
enum_val[0] = 11;
H5.H5Tenum_insert(dtype_enum_id, "GREEN", enum_val);
enum_val[0] = 12;
H5.H5Tenum_insert(dtype_enum_id, "BLUE", enum_val);
enum_val[0] = 13;
H5.H5Tenum_insert(dtype_enum_id, "ORANGE", enum_val);
enum_val[0] = 14;
H5.H5Tenum_insert(dtype_enum_id, "YELLOW", enum_val);
// Query member number and member index by member name, for enumeration type.
assertTrue("Can't get member number", H5.H5Tget_nmembers(dtype_enum_id) == 5);
assertTrue("Can't get correct index number",
H5.H5Tget_member_index(dtype_enum_id, "ORANGE") == 3);
// Query member value by member name, for enumeration type
H5.H5Tenum_valueof(dtype_enum_id, "ORANGE", enum_val);
assertTrue("Incorrect value for enum member", enum_val[0] == 13);
// Commit enumeration datatype and close it */
H5.H5Tcommit(H5fid, enum_type, dtype_enum_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
H5.H5Tclose(dtype_enum_id);
// Open the dataytpe for query
dtype_enum_id = H5.H5Topen(H5fid, enum_type, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DArrayenum_rw:H5Tcreate", dtype_enum_id >= 0);
// Query member number and member index by member name, for enumeration type
assertTrue("Can't get member number", H5.H5Tget_nmembers(dtype_enum_id) == 5);
assertTrue("Can't get correct index number",
H5.H5Tget_member_index(dtype_enum_id, "ORANGE") == 3);
// Query member value by member name, for enumeration type
H5.H5Tenum_valueof(dtype_enum_id, "ORANGE", enum_val);
assertTrue("Incorrect value for enum member", enum_val[0] == 13);
// Query member value by member index, for enumeration type
H5.H5Tget_member_value(dtype_enum_id, 2, enum_val);
assertTrue("Incorrect value for enum member", enum_val[0] == 12);
// Query member name by member value, for enumeration type
enum_val[0] = 14;
enum_name = H5.H5Tenum_nameof(dtype_enum_id, enum_val, 16);
assertTrue("Incorrect name for enum member", enum_name.compareTo("YELLOW") == 0);
ArrayList[] arr_enum_data = new ArrayList[4];
try {
// Write Integer data
arr_enum_data[0] = new ArrayList<Integer>(Arrays.asList(10, 11, 12, 13));
arr_enum_data[1] = new ArrayList<Integer>(Arrays.asList(11, 12, 13, 14));
arr_enum_data[2] = new ArrayList<Integer>(Arrays.asList(12, 13, 14, 10));
arr_enum_data[3] = new ArrayList<Integer>(Arrays.asList(13, 14, 10, 11));
Class dataClass = arr_enum_data.getClass();
assertTrue("testH5DArrayenum_wr.getClass: " + dataClass, dataClass.isArray());
try {
dtype_arr_enum_id = H5.H5Tarray_create(HDF5Constants.H5T_STD_U32LE, 1, dims);
assertTrue("testH5DArrayenum_wr.H5Tarray_create: ", dtype_arr_enum_id >= 0);
}
catch (Exception err) {
if (dtype_arr_enum_id > 0)
try {
H5.H5Tclose(dtype_arr_enum_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("H5.testH5DArrayenum_wr: " + err);
}
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue(dspace_id > 0);
dset_enum_id = H5.H5Dcreate(H5fid, dset_enum_name, dtype_arr_enum_id, dspace_id,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DVLwr: ", dset_enum_id >= 0);
H5.H5DwriteVL(dset_enum_id, dtype_arr_enum_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, arr_enum_data);
}
catch (Throwable err) {
if (dset_enum_id > 0)
try {
H5.H5Dclose(dset_enum_id);
}
catch (Exception ex) {
}
if (dtype_enum_id > 0)
try {
H5.H5Tclose(dtype_enum_id);
}
catch (Exception ex) {
}
if (dtype_arr_enum_id > 0)
try {
H5.H5Tclose(dtype_arr_enum_id);
}
catch (Exception ex) {
}
err.printStackTrace();
fail("testH5DArrayenum_rw:query " + err);
}
finally {
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
for (int j = 0; j < dims.length; j++)
lsize *= dims[j];
// Read Integer data
ArrayList[] arr_readbuf = new ArrayList[4];
for (int j = 0; j < lsize; j++)
arr_readbuf[j] = new ArrayList<Integer>();
try {
H5.H5DreadVL(dset_enum_id, dtype_arr_enum_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, arr_readbuf);
}
catch (Exception ex) {
ex.printStackTrace();
}
assertTrue("testH5DVLArrayenum_wr:" + arr_readbuf[0].get(0),
arr_enum_data[0].get(0).equals(arr_readbuf[0].get(0)));
assertTrue("testH5DVLArrayenum_wr:" + arr_readbuf[1].get(0),
arr_enum_data[1].get(0).equals(arr_readbuf[1].get(0)));
assertTrue("testH5DVLArrayenum_wr:" + arr_readbuf[2].get(0),
arr_enum_data[2].get(0).equals(arr_readbuf[2].get(0)));
assertTrue("testH5DVLArrayenum_wr:" + arr_readbuf[3].get(0),
arr_enum_data[3].get(0).equals(arr_readbuf[3].get(0)));
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.testH5DArrayenum_wr: " + err);
}
finally {
if (dset_enum_id > 0)
try {
H5.H5Dclose(dset_enum_id);
}
catch (Exception ex) {
}
if (dtype_enum_id > 0)
try {
H5.H5Tclose(dtype_enum_id);
}
catch (Exception ex) {
}
if (dtype_arr_enum_id > 0)
try {
H5.H5Tclose(dtype_arr_enum_id);
}
catch (Exception ex) {
}
}
}
@Test
public void testH5Dwrite_readCompound()
{
String dset_name = "CompoundData";
long dset_id = HDF5Constants.H5I_INVALID_HID;
long compound_type_id = HDF5Constants.H5I_INVALID_HID;
long dataspace_id = HDF5Constants.H5I_INVALID_HID;
final int ARRAY_SIZE = 4;
// Create test data - 4 sensor readings
ArrayList[] write_data = new ArrayList[ARRAY_SIZE];
write_data[0] = new TestSensor(1153, "Exterior (static)", 53.23, 24.57).toArrayList();
write_data[1] = new TestSensor(1184, "Intake", 55.12, 22.95).toArrayList();
write_data[2] = new TestSensor(1027, "Intake manifold", 103.55, 31.23).toArrayList();
write_data[3] = new TestSensor(1313, "Exhaust manifold", 1252.89, 84.11).toArrayList();
try {
// Create compound datatype
compound_type_id = TestSensor.createMemType();
assertTrue("testH5Dwrite_readCompound: compound type created", compound_type_id >= 0);
// Create dataspace (1D, 4 elements)
long[] dims = {ARRAY_SIZE};
dataspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue("testH5Dwrite_readCompound: dataspace created", dataspace_id >= 0);
// Create dataset
dset_id =
H5.H5Dcreate(H5fid, dset_name, compound_type_id, dataspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5Dwrite_readCompound: dataset created", dset_id >= 0);
// Write compound data
H5.H5DwriteVL(dset_id, compound_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, write_data);
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
// Read compound data back
ArrayList[] read_data = new ArrayList[ARRAY_SIZE];
H5.H5DreadVL(dset_id, compound_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, read_data);
// Validate sensor 0
assertNotNull("testH5Dwrite_readCompound: read_data[0] not null", read_data[0]);
TestSensor sensor0 = new TestSensor(read_data[0]);
assertEquals("testH5Dwrite_readCompound: sensor0 serial_no", 1153, sensor0.serial_no);
assertEquals("testH5Dwrite_readCompound: sensor0 location", "Exterior (static)",
sensor0.location.trim());
assertEquals("testH5Dwrite_readCompound: sensor0 temperature", 53.23, sensor0.temperature, 0.01);
assertEquals("testH5Dwrite_readCompound: sensor0 pressure", 24.57, sensor0.pressure, 0.01);
// Validate sensor 1
assertNotNull("testH5Dwrite_readCompound: read_data[1] not null", read_data[1]);
TestSensor sensor1 = new TestSensor(read_data[1]);
assertEquals("testH5Dwrite_readCompound: sensor1 serial_no", 1184, sensor1.serial_no);
assertEquals("testH5Dwrite_readCompound: sensor1 location", "Intake", sensor1.location.trim());
assertEquals("testH5Dwrite_readCompound: sensor1 temperature", 55.12, sensor1.temperature, 0.01);
assertEquals("testH5Dwrite_readCompound: sensor1 pressure", 22.95, sensor1.pressure, 0.01);
// Validate sensor 2
assertNotNull("testH5Dwrite_readCompound: read_data[2] not null", read_data[2]);
TestSensor sensor2 = new TestSensor(read_data[2]);
assertEquals("testH5Dwrite_readCompound: sensor2 serial_no", 1027, sensor2.serial_no);
assertEquals("testH5Dwrite_readCompound: sensor2 location", "Intake manifold",
sensor2.location.trim());
assertEquals("testH5Dwrite_readCompound: sensor2 temperature", 103.55, sensor2.temperature, 0.01);
assertEquals("testH5Dwrite_readCompound: sensor2 pressure", 31.23, sensor2.pressure, 0.01);
// Validate sensor 3
assertNotNull("testH5Dwrite_readCompound: read_data[3] not null", read_data[3]);
TestSensor sensor3 = new TestSensor(read_data[3]);
assertEquals("testH5Dwrite_readCompound: sensor3 serial_no", 1313, sensor3.serial_no);
assertEquals("testH5Dwrite_readCompound: sensor3 location", "Exhaust manifold",
sensor3.location.trim());
assertEquals("testH5Dwrite_readCompound: sensor3 temperature", 1252.89, sensor3.temperature,
0.01);
assertEquals("testH5Dwrite_readCompound: sensor3 pressure", 84.11, sensor3.pressure, 0.01);
}
catch (Throwable err) {
err.printStackTrace();
fail("H5.testH5Dwrite_readCompound: " + err);
}
finally {
if (dset_id > 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
if (compound_type_id > 0)
try {
H5.H5Tclose(compound_type_id);
}
catch (Exception ex) {
}
if (dataspace_id > 0)
try {
H5.H5Sclose(dataspace_id);
}
catch (Exception ex) {
}
}
}
/**
* Test H5Dwrite_VLStrings and H5Dread_VLStrings round-trip
*/
@Ignore
public void testH5D_VLStrings_write_read_roundtrip()
{
String dsetName = "/VLStringDataset_roundtrip";
long strType = HDF5Constants.H5I_INVALID_HID;
long dsetId = HDF5Constants.H5I_INVALID_HID;
long dsetSpace = HDF5Constants.H5I_INVALID_HID;
try {
// Create variable-length string type
strType = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
H5.H5Tset_size(strType, HDF5Constants.H5T_VARIABLE);
// Create dataspace for 2D array of strings
long[] dims = {2, 3};
dsetSpace = H5.H5Screate_simple(2, dims, null);
// Create dataset
dsetId = H5.H5Dcreate(H5fid, dsetName, strType, dsetSpace, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("H5Dcreate failed", dsetId >= 0);
// Write 6 strings (2x3 array flattened)
String[] writeData = {"String 0", "String 1", "String 2", "String 3", "String 4", "String 5"};
int status = H5.H5Dwrite_VLStrings(dsetId, strType, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, writeData);
assertTrue("H5Dwrite_VLStrings failed", status >= 0);
// Read back
String[] readData = new String[6];
status = H5.H5Dread_VLStrings(dsetId, strType, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, readData);
assertTrue("H5Dread_VLStrings failed", status >= 0);
// Verify all strings
for (int i = 0; i < 6; i++) {
assertEquals("String " + i + " mismatch", writeData[i], readData[i]);
}
}
catch (Exception ex) {
ex.printStackTrace();
fail("Exception: " + ex.getMessage());
}
finally {
try {
if (dsetId >= 0)
H5.H5Dclose(dsetId);
}
catch (Exception ex) {
}
try {
if (dsetSpace >= 0)
H5.H5Sclose(dsetSpace);
}
catch (Exception ex) {
}
try {
if (strType >= 0)
H5.H5Tclose(strType);
}
catch (Exception ex) {
}
}
}
/**
* Test round-trip with empty strings
*/
@Ignore
public void testH5D_VLStrings_roundtrip_empty()
{
String dsetName = "/VLStringDataset_empty";
long strType = HDF5Constants.H5I_INVALID_HID;
long dsetId = HDF5Constants.H5I_INVALID_HID;
long dsetSpace = HDF5Constants.H5I_INVALID_HID;
try {
strType = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
H5.H5Tset_size(strType, HDF5Constants.H5T_VARIABLE);
long[] dims = {4};
dsetSpace = H5.H5Screate_simple(1, dims, null);
dsetId = H5.H5Dcreate(H5fid, dsetName, strType, dsetSpace, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
// Write mix of empty and non-empty strings
String[] writeData = {"", "Not empty", "", "Also not empty"};
int status = H5.H5Dwrite_VLStrings(dsetId, strType, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, writeData);
assertTrue("H5Dwrite_VLStrings failed", status >= 0);
// Read back
String[] readData = new String[4];
status = H5.H5Dread_VLStrings(dsetId, strType, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, readData);
assertTrue("H5Dread_VLStrings failed", status >= 0);
// Verify empty strings preserved
assertEquals("First should be empty", "", readData[0]);
assertEquals("Second should match", "Not empty", readData[1]);
assertEquals("Third should be empty", "", readData[2]);
assertEquals("Fourth should match", "Also not empty", readData[3]);
}
catch (Exception ex) {
ex.printStackTrace();
fail("Exception: " + ex.getMessage());
}
finally {
try {
if (dsetId >= 0)
H5.H5Dclose(dsetId);
}
catch (Exception ex) {
}
try {
if (dsetSpace >= 0)
H5.H5Sclose(dsetSpace);
}
catch (Exception ex) {
}
try {
if (strType >= 0)
H5.H5Tclose(strType);
}
catch (Exception ex) {
}
}
}
/**
* Test round-trip with large strings
*/
@Ignore
public void testH5D_VLStrings_roundtrip_large()
{
String dsetName = "/VLStringDataset_large";
long strType = HDF5Constants.H5I_INVALID_HID;
long dsetId = HDF5Constants.H5I_INVALID_HID;
long dsetSpace = HDF5Constants.H5I_INVALID_HID;
try {
strType = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
H5.H5Tset_size(strType, HDF5Constants.H5T_VARIABLE);
long[] dims = {3};
dsetSpace = H5.H5Screate_simple(1, dims, null);
dsetId = H5.H5Dcreate(H5fid, dsetName, strType, dsetSpace, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
// Create large strings (>1KB each)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 200; i++) {
sb.append("This is test string content ");
}
String largeString = sb.toString();
String[] writeData = {largeString + " [0]", largeString + " [1]", largeString + " [2]"};
int status = H5.H5Dwrite_VLStrings(dsetId, strType, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, writeData);
assertTrue("H5Dwrite_VLStrings failed", status >= 0);
String[] readData = new String[3];
status = H5.H5Dread_VLStrings(dsetId, strType, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, readData);
assertTrue("H5Dread_VLStrings failed", status >= 0);
for (int i = 0; i < 3; i++) {
assertEquals("Large string " + i + " mismatch", writeData[i], readData[i]);
assertTrue("String should be > 1KB", readData[i].length() > 1024);
}
}
catch (Exception ex) {
ex.printStackTrace();
fail("Exception: " + ex.getMessage());
}
finally {
try {
if (dsetId >= 0)
H5.H5Dclose(dsetId);
}
catch (Exception ex) {
}
try {
if (dsetSpace >= 0)
H5.H5Sclose(dsetSpace);
}
catch (Exception ex) {
}
try {
if (strType >= 0)
H5.H5Tclose(strType);
}
catch (Exception ex) {
}
}
}
/*
* Verify H5DreadVL safe throws a Java exception
* when called with a malformed buffer shape for an ARRAY-of-varstr dataset.
*/
@Test
public void testH5DArray_string_buffer_flat_StringArray() throws Throwable
{
String dset_str_name = "ArrayStringdata_flat";
long dset_str_id = HDF5Constants.H5I_INVALID_HID;
long dtype_str_id = HDF5Constants.H5I_INVALID_HID;
long varstr_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] strdims = {3};
long[] dims = {2};
long lsize = 1;
String[] row0 = {"a", "bb", "ccc"};
String[] row1 = {"dd", "ee", "fff"};
ArrayList[] arr_str_data = new ArrayList[2];
arr_str_data[0] = new ArrayList<String>(Arrays.asList(row0));
arr_str_data[1] = new ArrayList<String>(Arrays.asList(row1));
try {
varstr_id = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
H5.H5Tset_size(varstr_id, HDF5Constants.H5T_VARIABLE);
dtype_str_id = H5.H5Tarray_create(varstr_id, 1, strdims);
dspace_id = H5.H5Screate_simple(1, dims, null);
dset_str_id =
H5.H5Dcreate(H5fid, dset_str_name, dtype_str_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
H5.H5DwriteVL(dset_str_id, dtype_str_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, arr_str_data);
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
for (int j = 0; j < dims.length; j++)
lsize *= dims[j];
// Malformed buffer: a flat String[dims*array_dim], not
// ArrayList[dims] of array_dim Strings.
int flatLen = (int)lsize * (int)strdims[0];
String[] badBuf = new String[flatLen];
for (int j = 0; j < flatLen; j++)
badBuf[j] = "";
// The JNI must not segfault here regardless of what badBuf looks
// like. Either it correctly populates the slots or it throws.
try {
H5.H5DreadVL(dset_str_id, dtype_str_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, badBuf);
}
catch (Exception ex) {
// Accepted outcome: graceful Java-level error.
return;
}
assertNotNull("badBuf[0] should not be null after H5DreadVL", badBuf[0]);
}
finally {
if (dset_str_id > 0)
try {
H5.H5Dclose(dset_str_id);
}
catch (Exception ex) {
}
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
if (dtype_str_id > 0)
try {
H5.H5Tclose(dtype_str_id);
}
catch (Exception ex) {
}
if (varstr_id > 0)
try {
H5.H5Tclose(varstr_id);
}
catch (Exception ex) {
}
}
}
/*
* Verify H5DwriteVL safely throws a Java exception
* when called with a malformed buffer shape for an ARRAY-of-varstr dataset.
*/
@Test
public void testH5DArray_string_buffer_flat_StringArray_write() throws Throwable
{
String dset_str_name = "ArrayStringdata_flat_write";
long dset_str_id = HDF5Constants.H5I_INVALID_HID;
long dtype_str_id = HDF5Constants.H5I_INVALID_HID;
long varstr_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] strdims = {3};
long[] dims = {2};
try {
varstr_id = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
H5.H5Tset_size(varstr_id, HDF5Constants.H5T_VARIABLE);
dtype_str_id = H5.H5Tarray_create(varstr_id, 1, strdims);
dspace_id = H5.H5Screate_simple(1, dims, null);
dset_str_id =
H5.H5Dcreate(H5fid, dset_str_name, dtype_str_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
// Malformed buffer: a flat String[dims*array_dim], not
// ArrayList[dims] of array_dim Strings.
int flatLen = (int)dims[0] * (int)strdims[0];
String[] flatBuf = new String[flatLen];
for (int j = 0; j < flatLen; j++)
flatBuf[j] = "s" + j;
try {
H5.H5DwriteVL(dset_str_id, dtype_str_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, flatBuf);
}
catch (Exception ex) {
// Accepted outcome: graceful Java-level error.
return;
}
// If we reach here, no exception was thrown. Worst case is the JVM
// segfaults before this line. If it accepted the write silently,
// that itself indicates the JNI doesn't validate the buffer shape.
}
finally {
if (dset_str_id > 0)
try {
H5.H5Dclose(dset_str_id);
}
catch (Exception ex) {
}
if (dspace_id > 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
if (dtype_str_id > 0)
try {
H5.H5Tclose(dtype_str_id);
}
catch (Exception ex) {
}
if (varstr_id > 0)
try {
H5.H5Tclose(varstr_id);
}
catch (Exception ex) {
}
}
}
/*
* Build a 1-D dataset of type COMPOUND { seq: VLEN { int32 }, n: int32 }
* inside the per-test file (H5fid) and write canonical data via H5DwriteVL.
* Closes the vlen/compound/dataspace ids internally and returns only the
* open dataset id; the caller closes the dataset and re-fetches the type
* via H5Dget_type if needed.
*/
private long writeCompoundOfVlenDataset(String dsetName) throws Exception
{
long vlen_tid = HDF5Constants.H5I_INVALID_HID;
long cmpd_tid = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long dset_id = HDF5Constants.H5I_INVALID_HID;
try {
vlen_tid = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_INT);
assertTrue("writeCompoundOfVlenDataset: H5Tvlen_create: ", vlen_tid >= 0);
long hvlSize = H5.H5Tget_size(vlen_tid);
long intSize = H5.H5Tget_size(HDF5Constants.H5T_NATIVE_INT);
long packedSize = hvlSize + intSize;
cmpd_tid = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND, packedSize);
assertTrue("writeCompoundOfVlenDataset: H5Tcreate compound: ", cmpd_tid >= 0);
H5.H5Tinsert(cmpd_tid, "seq", 0, vlen_tid);
H5.H5Tinsert(cmpd_tid, "n", hvlSize, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tpack(cmpd_tid);
long[] dims = {2};
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue("writeCompoundOfVlenDataset: H5Screate_simple: ", dspace_id >= 0);
dset_id = H5.H5Dcreate(H5fid, dsetName, cmpd_tid, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("writeCompoundOfVlenDataset: H5Dcreate: ", dset_id >= 0);
ArrayList<Integer> seq0 = new ArrayList<>();
seq0.add(1);
seq0.add(2);
seq0.add(3);
ArrayList<Integer> seq1 = new ArrayList<>();
seq1.add(5);
seq1.add(6);
ArrayList[] write_data = new ArrayList[2];
ArrayList<Object> rec0 = new ArrayList<>();
rec0.add(seq0);
rec0.add(Integer.valueOf(4));
write_data[0] = rec0;
ArrayList<Object> rec1 = new ArrayList<>();
rec1.add(seq1);
rec1.add(Integer.valueOf(7));
write_data[1] = rec1;
H5.H5DwriteVL(dset_id, cmpd_tid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, write_data);
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
}
finally {
if (dspace_id >= 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
if (cmpd_tid >= 0)
try {
H5.H5Tclose(cmpd_tid);
}
catch (Exception ex) {
}
if (vlen_tid >= 0)
try {
H5.H5Tclose(vlen_tid);
}
catch (Exception ex) {
}
}
return dset_id;
}
/*
* Read a 1-D dataset whose type is COMPOUND { seq: VLEN { int32 }, n: int32 }.
* Uses the canonical calling pattern: pass ArrayList[] with null slots
* and let the native code allocate each per-row record.
*/
@Test
public void testH5Dread_compound_of_vlen()
{
long dset_id = HDF5Constants.H5I_INVALID_HID;
long file_type_id = HDF5Constants.H5I_INVALID_HID;
final int N_ROWS = 2;
try {
dset_id = writeCompoundOfVlenDataset("cmpd_of_vlen_rd");
file_type_id = H5.H5Dget_type(dset_id);
assertTrue("testH5Dread_compound_of_vlen: H5Dget_type: ", file_type_id >= 0);
ArrayList[] read_data = new ArrayList[N_ROWS];
H5.H5DreadVL(dset_id, file_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, read_data);
assertNotNull("testH5Dread_compound_of_vlen: read_data[0] not null", read_data[0]);
assertNotNull("testH5Dread_compound_of_vlen: read_data[1] not null", read_data[1]);
assertEquals("testH5Dread_compound_of_vlen: row 0 record has 2 members", 2, read_data[0].size());
assertEquals("testH5Dread_compound_of_vlen: row 1 record has 2 members", 2, read_data[1].size());
Object seq0obj = read_data[0].get(0);
Object seq1obj = read_data[1].get(0);
assertTrue("testH5Dread_compound_of_vlen: row 0 seq is ArrayList, got " +
(seq0obj == null ? "null" : seq0obj.getClass().getName()),
seq0obj instanceof ArrayList);
assertTrue("testH5Dread_compound_of_vlen: row 1 seq is ArrayList, got " +
(seq1obj == null ? "null" : seq1obj.getClass().getName()),
seq1obj instanceof ArrayList);
ArrayList<?> seq0_read = (ArrayList<?>)seq0obj;
ArrayList<?> seq1_read = (ArrayList<?>)seq1obj;
assertEquals("testH5Dread_compound_of_vlen: row 0 seq length", 3, seq0_read.size());
assertEquals("testH5Dread_compound_of_vlen: row 1 seq length", 2, seq1_read.size());
assertEquals("testH5Dread_compound_of_vlen: row 0 seq[0]", Integer.valueOf(1), seq0_read.get(0));
assertEquals("testH5Dread_compound_of_vlen: row 0 seq[1]", Integer.valueOf(2), seq0_read.get(1));
assertEquals("testH5Dread_compound_of_vlen: row 0 seq[2]", Integer.valueOf(3), seq0_read.get(2));
assertEquals("testH5Dread_compound_of_vlen: row 1 seq[0]", Integer.valueOf(5), seq1_read.get(0));
assertEquals("testH5Dread_compound_of_vlen: row 1 seq[1]", Integer.valueOf(6), seq1_read.get(1));
assertEquals("testH5Dread_compound_of_vlen: row 0 n", Integer.valueOf(4), read_data[0].get(1));
assertEquals("testH5Dread_compound_of_vlen: row 1 n", Integer.valueOf(7), read_data[1].get(1));
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5Dread_compound_of_vlen: " + err);
}
finally {
if (file_type_id >= 0)
try {
H5.H5Tclose(file_type_id);
}
catch (Exception ex) {
}
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
}
}
/*
* Round-trip a compound-of-vlen dataset through H5DwriteVL and H5DreadVL.
* Reuses the writeCompoundOfVlenDataset helper to exercise the write path,
* then reads back and asserts the full row contents.
*/
@Test
public void testH5Dwrite_compound_of_vlen()
{
long dset_id = HDF5Constants.H5I_INVALID_HID;
long file_type_id = HDF5Constants.H5I_INVALID_HID;
final int N_ROWS = 2;
try {
dset_id = writeCompoundOfVlenDataset("cmpd_of_vlen_wr");
file_type_id = H5.H5Dget_type(dset_id);
assertTrue("testH5Dwrite_compound_of_vlen: H5Dget_type: ", file_type_id >= 0);
ArrayList[] read_data = new ArrayList[N_ROWS];
H5.H5DreadVL(dset_id, file_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, read_data);
assertNotNull("testH5Dwrite_compound_of_vlen: read_data[0] not null", read_data[0]);
assertNotNull("testH5Dwrite_compound_of_vlen: read_data[1] not null", read_data[1]);
assertEquals("testH5Dwrite_compound_of_vlen: row 0 record has 2 members", 2, read_data[0].size());
assertEquals("testH5Dwrite_compound_of_vlen: row 1 record has 2 members", 2, read_data[1].size());
ArrayList<?> seq0_read = (ArrayList<?>)read_data[0].get(0);
ArrayList<?> seq1_read = (ArrayList<?>)read_data[1].get(0);
assertEquals("testH5Dwrite_compound_of_vlen: row 0 seq length", 3, seq0_read.size());
assertEquals("testH5Dwrite_compound_of_vlen: row 1 seq length", 2, seq1_read.size());
assertEquals("testH5Dwrite_compound_of_vlen: row 0 seq[0]", Integer.valueOf(1), seq0_read.get(0));
assertEquals("testH5Dwrite_compound_of_vlen: row 0 seq[1]", Integer.valueOf(2), seq0_read.get(1));
assertEquals("testH5Dwrite_compound_of_vlen: row 0 seq[2]", Integer.valueOf(3), seq0_read.get(2));
assertEquals("testH5Dwrite_compound_of_vlen: row 1 seq[0]", Integer.valueOf(5), seq1_read.get(0));
assertEquals("testH5Dwrite_compound_of_vlen: row 1 seq[1]", Integer.valueOf(6), seq1_read.get(1));
assertEquals("testH5Dwrite_compound_of_vlen: row 0 n", Integer.valueOf(4), read_data[0].get(1));
assertEquals("testH5Dwrite_compound_of_vlen: row 1 n", Integer.valueOf(7), read_data[1].get(1));
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5Dwrite_compound_of_vlen: " + err);
}
finally {
if (file_type_id >= 0)
try {
H5.H5Tclose(file_type_id);
}
catch (Exception ex) {
}
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
}
}
/*
* Negative tests for the API-level buffer-contract verification in H5DwriteVL.
* Each supplies a malformed buffer for a COMPOUND { seq: VLEN int, n: int }
* dataset and asserts a clean IllegalArgumentException is raised before any
* native write, rather than a SIGSEGV or silent corruption.
*/
/* Buffer shorter than the selection must be rejected (would otherwise overrun
* the raw write buffer in H5Dwrite). */
@Test
public void testH5DwriteVL_undersized_buffer()
{
long dset_id = HDF5Constants.H5I_INVALID_HID;
long file_type_id = HDF5Constants.H5I_INVALID_HID;
try {
dset_id = writeCompoundOfVlenDataset("cmpd_of_vlen_wr_undersized");
file_type_id = H5.H5Dget_type(dset_id);
// Dataset has 2 rows; supply only 1.
ArrayList<Integer> seq = new ArrayList<>();
seq.add(1);
ArrayList<Object> rec = new ArrayList<>();
rec.add(seq);
rec.add(Integer.valueOf(2));
ArrayList[] bad = new ArrayList[1];
bad[0] = rec;
try {
H5.H5DwriteVL(dset_id, file_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, bad);
fail("testH5DwriteVL_undersized_buffer: expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
// expected
}
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5DwriteVL_undersized_buffer: " + err);
}
finally {
if (file_type_id >= 0)
try {
H5.H5Tclose(file_type_id);
}
catch (Exception ex) {
}
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
}
}
/* A compound member whose Java type is wrong (String where an Integer is
* expected) must be rejected instead of crashing in translate_atomic_wbuf. */
@Test
public void testH5DwriteVL_compound_wrong_member_type()
{
long dset_id = HDF5Constants.H5I_INVALID_HID;
long file_type_id = HDF5Constants.H5I_INVALID_HID;
try {
dset_id = writeCompoundOfVlenDataset("cmpd_of_vlen_wr_badmember");
file_type_id = H5.H5Dget_type(dset_id);
ArrayList[] bad = new ArrayList[2];
ArrayList<Integer> seq0 = new ArrayList<>();
seq0.add(1);
ArrayList<Object> rec0 = new ArrayList<>();
rec0.add(seq0);
rec0.add(Integer.valueOf(4));
bad[0] = rec0;
// row 1: the 'n' member is a String, not an Integer.
ArrayList<Integer> seq1 = new ArrayList<>();
seq1.add(5);
ArrayList<Object> rec1 = new ArrayList<>();
rec1.add(seq1);
rec1.add("not an int");
bad[1] = rec1;
try {
H5.H5DwriteVL(dset_id, file_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, bad);
fail("testH5DwriteVL_compound_wrong_member_type: expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
// expected
}
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5DwriteVL_compound_wrong_member_type: " + err);
}
finally {
if (file_type_id >= 0)
try {
H5.H5Tclose(file_type_id);
}
catch (Exception ex) {
}
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
}
}
/* A VLEN member that is not an ArrayList (here a String) must be rejected
* instead of being mis-read as a list. */
@Test
public void testH5DwriteVL_vlen_element_not_arraylist()
{
long dset_id = HDF5Constants.H5I_INVALID_HID;
long file_type_id = HDF5Constants.H5I_INVALID_HID;
try {
dset_id = writeCompoundOfVlenDataset("cmpd_of_vlen_wr_notlist");
file_type_id = H5.H5Dget_type(dset_id);
ArrayList[] bad = new ArrayList[2];
// row 0: the 'seq' member should be an ArrayList but is a String.
ArrayList<Object> rec0 = new ArrayList<>();
rec0.add("not a list");
rec0.add(Integer.valueOf(4));
bad[0] = rec0;
ArrayList<Integer> seq1 = new ArrayList<>();
seq1.add(5);
ArrayList<Object> rec1 = new ArrayList<>();
rec1.add(seq1);
rec1.add(Integer.valueOf(7));
bad[1] = rec1;
try {
H5.H5DwriteVL(dset_id, file_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, bad);
fail("testH5DwriteVL_vlen_element_not_arraylist: expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
// expected
}
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5DwriteVL_vlen_element_not_arraylist: " + err);
}
finally {
if (file_type_id >= 0)
try {
H5.H5Tclose(file_type_id);
}
catch (Exception ex) {
}
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
}
}
/* A compound row with the wrong number of members must be rejected. */
@Test
public void testH5DwriteVL_compound_wrong_member_count()
{
long dset_id = HDF5Constants.H5I_INVALID_HID;
long file_type_id = HDF5Constants.H5I_INVALID_HID;
try {
dset_id = writeCompoundOfVlenDataset("cmpd_of_vlen_wr_badcount");
file_type_id = H5.H5Dget_type(dset_id);
ArrayList[] bad = new ArrayList[2];
// row 0: only one member instead of two ('n' is missing).
ArrayList<Integer> seq0 = new ArrayList<>();
seq0.add(1);
ArrayList<Object> rec0 = new ArrayList<>();
rec0.add(seq0);
bad[0] = rec0;
ArrayList<Integer> seq1 = new ArrayList<>();
seq1.add(5);
ArrayList<Object> rec1 = new ArrayList<>();
rec1.add(seq1);
rec1.add(Integer.valueOf(7));
bad[1] = rec1;
try {
H5.H5DwriteVL(dset_id, file_type_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, bad);
fail("testH5DwriteVL_compound_wrong_member_count: expected IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
// expected
}
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5DwriteVL_compound_wrong_member_count: " + err);
}
finally {
if (file_type_id >= 0)
try {
H5.H5Tclose(file_type_id);
}
catch (Exception ex) {
}
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
}
}
/*
* Read a 1-D dataset whose type is VLEN { COMPOUND { A: int, B: int } }. The
* caller passes a freshly allocated array with null row slots, which is the
* canonical read pattern: the JNI installs a freshly allocated ArrayList into
* each slot. Exercises the translate_rbuf H5T_VLEN top-level case for a
* compound element type.
*/
@Test
public void testH5Dread_vlen_of_compound()
{
long cmpd_tid = HDF5Constants.H5I_INVALID_HID;
long vlen_tid = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long dset_id = HDF5Constants.H5I_INVALID_HID;
final int N_ROWS = 2;
try {
long intSize = H5.H5Tget_size(HDF5Constants.H5T_NATIVE_INT);
cmpd_tid = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND, 2 * intSize);
H5.H5Tinsert(cmpd_tid, "A", 0, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tinsert(cmpd_tid, "B", intSize, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tpack(cmpd_tid);
vlen_tid = H5.H5Tvlen_create(cmpd_tid);
long[] dims = {N_ROWS};
dspace_id = H5.H5Screate_simple(1, dims, null);
dset_id = H5.H5Dcreate(H5fid, "vlen_of_cmpd_rd", vlen_tid, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5Dread_vlen_of_compound: H5Dcreate: ", dset_id >= 0);
// row 0: 1 element [ { A=1, B=2 } ]
// row 1: 2 elements [ { A=3, B=4 }, { A=5, B=6 } ]
ArrayList<Object> row0_elem0 = new ArrayList<>();
row0_elem0.add(Integer.valueOf(1));
row0_elem0.add(Integer.valueOf(2));
ArrayList<Object> row0 = new ArrayList<>();
row0.add(row0_elem0);
ArrayList<Object> row1_elem0 = new ArrayList<>();
row1_elem0.add(Integer.valueOf(3));
row1_elem0.add(Integer.valueOf(4));
ArrayList<Object> row1_elem1 = new ArrayList<>();
row1_elem1.add(Integer.valueOf(5));
row1_elem1.add(Integer.valueOf(6));
ArrayList<Object> row1 = new ArrayList<>();
row1.add(row1_elem0);
row1.add(row1_elem1);
ArrayList[] write_data = new ArrayList[N_ROWS];
write_data[0] = row0;
write_data[1] = row1;
H5.H5DwriteVL(dset_id, vlen_tid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, write_data);
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
// Freshly allocated array with null row slots; the JNI fills each slot.
ArrayList[] read_data = new ArrayList[N_ROWS];
H5.H5DreadVL(dset_id, vlen_tid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, read_data);
assertNotNull("testH5Dread_vlen_of_compound: row 0 not null", read_data[0]);
assertNotNull("testH5Dread_vlen_of_compound: row 1 not null", read_data[1]);
assertEquals("testH5Dread_vlen_of_compound: row 0 has 1 element", 1, read_data[0].size());
assertEquals("testH5Dread_vlen_of_compound: row 1 has 2 elements", 2, read_data[1].size());
ArrayList<?> r0e0 = (ArrayList<?>)read_data[0].get(0);
assertEquals("row 0 elem 0 A", Integer.valueOf(1), r0e0.get(0));
assertEquals("row 0 elem 0 B", Integer.valueOf(2), r0e0.get(1));
ArrayList<?> r1e0 = (ArrayList<?>)read_data[1].get(0);
assertEquals("row 1 elem 0 A", Integer.valueOf(3), r1e0.get(0));
assertEquals("row 1 elem 0 B", Integer.valueOf(4), r1e0.get(1));
ArrayList<?> r1e1 = (ArrayList<?>)read_data[1].get(1);
assertEquals("row 1 elem 1 A", Integer.valueOf(5), r1e1.get(0));
assertEquals("row 1 elem 1 B", Integer.valueOf(6), r1e1.get(1));
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5Dread_vlen_of_compound: " + err);
}
finally {
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
if (dspace_id >= 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
if (vlen_tid >= 0)
try {
H5.H5Tclose(vlen_tid);
}
catch (Exception ex) {
}
if (cmpd_tid >= 0)
try {
H5.H5Tclose(cmpd_tid);
}
catch (Exception ex) {
}
}
}
/*
* Read a 1-D dataset whose type is VLEN { COMPOUND { id: int, sub: COMPOUND { P: int, Q: int } } }.
* Per-row canonical shape (per testH5Dwrite_readCompound contract):
* row r ArrayList of vlen elements
* each element is ArrayList of 2 members [Integer id, ArrayList sub]
* sub is ArrayList of 2 members [Integer P, Integer Q]
*/
@Test
public void testH5Dread_vlen_of_nested_compound()
{
long inner_tid = HDF5Constants.H5I_INVALID_HID;
long outer_tid = HDF5Constants.H5I_INVALID_HID;
long vlen_tid = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long dset_id = HDF5Constants.H5I_INVALID_HID;
final int N_ROWS = 2;
try {
long intSize = H5.H5Tget_size(HDF5Constants.H5T_NATIVE_INT);
// inner = compound { P:int, Q:int }
inner_tid = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND, 2 * intSize);
H5.H5Tinsert(inner_tid, "P", 0, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tinsert(inner_tid, "Q", intSize, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tpack(inner_tid);
// outer = compound { id:int, sub:inner }
long innerSize = H5.H5Tget_size(inner_tid);
outer_tid = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND, intSize + innerSize);
H5.H5Tinsert(outer_tid, "id", 0, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tinsert(outer_tid, "sub", intSize, inner_tid);
H5.H5Tpack(outer_tid);
// vlen of outer
vlen_tid = H5.H5Tvlen_create(outer_tid);
long[] dims = {N_ROWS};
dspace_id = H5.H5Screate_simple(1, dims, null);
dset_id =
H5.H5Dcreate(H5fid, "vlen_of_nested_cmpd", vlen_tid, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5Dread_vlen_of_nested_compound: H5Dcreate: ", dset_id >= 0);
// row 0: 1 element [ { id=1, sub={ P=2, Q=3 } } ]
// row 1: 2 elements [ { id=4, sub={ P=5, Q=6 } }, { id=7, sub={ P=8, Q=9 } } ]
ArrayList<Object> row0_elem0_sub = new ArrayList<>();
row0_elem0_sub.add(Integer.valueOf(2));
row0_elem0_sub.add(Integer.valueOf(3));
ArrayList<Object> row0_elem0 = new ArrayList<>();
row0_elem0.add(Integer.valueOf(1));
row0_elem0.add(row0_elem0_sub);
ArrayList<Object> row0 = new ArrayList<>();
row0.add(row0_elem0);
ArrayList<Object> row1_elem0_sub = new ArrayList<>();
row1_elem0_sub.add(Integer.valueOf(5));
row1_elem0_sub.add(Integer.valueOf(6));
ArrayList<Object> row1_elem0 = new ArrayList<>();
row1_elem0.add(Integer.valueOf(4));
row1_elem0.add(row1_elem0_sub);
ArrayList<Object> row1_elem1_sub = new ArrayList<>();
row1_elem1_sub.add(Integer.valueOf(8));
row1_elem1_sub.add(Integer.valueOf(9));
ArrayList<Object> row1_elem1 = new ArrayList<>();
row1_elem1.add(Integer.valueOf(7));
row1_elem1.add(row1_elem1_sub);
ArrayList<Object> row1 = new ArrayList<>();
row1.add(row1_elem0);
row1.add(row1_elem1);
ArrayList[] write_data = new ArrayList[N_ROWS];
write_data[0] = row0;
write_data[1] = row1;
H5.H5DwriteVL(dset_id, vlen_tid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, write_data);
H5.H5Fflush(H5fid, HDF5Constants.H5F_SCOPE_LOCAL);
ArrayList[] read_data = new ArrayList[N_ROWS];
H5.H5DreadVL(dset_id, vlen_tid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, read_data);
assertNotNull("row 0 not null", read_data[0]);
assertNotNull("row 1 not null", read_data[1]);
assertEquals("row 0 has 1 element", 1, read_data[0].size());
assertEquals("row 1 has 2 elements", 2, read_data[1].size());
ArrayList<?> r0e0 = (ArrayList<?>)read_data[0].get(0);
assertEquals("row 0 elem 0 has 2 members", 2, r0e0.size());
assertEquals("row 0 elem 0 id", Integer.valueOf(1), r0e0.get(0));
ArrayList<?> r0e0sub = (ArrayList<?>)r0e0.get(1);
assertEquals("row 0 elem 0 sub has 2 members", 2, r0e0sub.size());
assertEquals("row 0 elem 0 sub.P", Integer.valueOf(2), r0e0sub.get(0));
assertEquals("row 0 elem 0 sub.Q", Integer.valueOf(3), r0e0sub.get(1));
ArrayList<?> r1e1 = (ArrayList<?>)read_data[1].get(1);
assertEquals("row 1 elem 1 has 2 members", 2, r1e1.size());
assertEquals("row 1 elem 1 id", Integer.valueOf(7), r1e1.get(0));
ArrayList<?> r1e1sub = (ArrayList<?>)r1e1.get(1);
assertEquals("row 1 elem 1 sub.P", Integer.valueOf(8), r1e1sub.get(0));
assertEquals("row 1 elem 1 sub.Q", Integer.valueOf(9), r1e1sub.get(1));
}
catch (Throwable err) {
err.printStackTrace();
fail("testH5Dread_vlen_of_nested_compound: " + err);
}
finally {
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
if (dspace_id >= 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
if (vlen_tid >= 0)
try {
H5.H5Tclose(vlen_tid);
}
catch (Exception ex) {
}
if (outer_tid >= 0)
try {
H5.H5Tclose(outer_tid);
}
catch (Exception ex) {
}
if (inner_tid >= 0)
try {
H5.H5Tclose(inner_tid);
}
catch (Exception ex) {
}
}
}
}