Files
hdf5/java/src-jni/test/TestH5D.java
T
Matt L 355f67ac37 Close datatype IDs derived from memory type in the JNI translation helpers (#6594)
* Close datatype IDs derived from the memory type in the JNI translate helpers

The object-tree read/write helpers in h5util.c derive a base datatype from
the memory type with H5Tget_super() for the variable-length, array and
complex classes, but never closed it. Because an hid_t is not reclaimed when
the native method returns, every read or write of such data leaked at least
one datatype ID for the lifetime of the process, and nested types leaked
one per level.

This PR updates the helpers to close the derived type in their done: blocks,
which covers both the success and the error paths, and to reset the id in the
compound loops to avoid the potential for double closes.

It also has the helpers release the class references that the per-element
helpers look up on entry. These are local references, so they were reclaimed
when the enclosing native method returned, but a compound read calls the helper
once per member per element and held one set per call until then. Releasing
them at the single exit bounds the count of references to the recursion depth.

* Add CHANGELOG entry for the JNI datatype ID leak fix

* Restrict the derived datatype close guards to strictly positive IDs

hid_t 0 is not a valid datatype ID, so H5Tclose(0) would fail.

* Revert "Restrict the derived datatype close guards to strictly positive IDs"

An hid_t of 0 not being a valid ID is a property of the current H5I
encoding rather than a documented guarantee, so the JNI helpers should
not depend on it.
2026-09-11 09:59:03 -05:00

3092 lines
119 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import hdf.hdf5lib.H5;
import hdf.hdf5lib.HDF5Constants;
import hdf.hdf5lib.HDFNativeData;
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; }
}
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);
}
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()
{
int[] buf_data = new int[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] = indx * jndx - jndx;
}
byte[] buf_array = HDFNativeData.intToByte(0, DIM_X * DIM_Y, 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 = HDFNativeData.byteToInt(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] == 0);
}
@Test
public void testH5Dfill()
{
int[] buf_data = new int[DIM_X * DIM_Y];
byte[] fill_value = HDFNativeData.intToByte(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] = indx * jndx - jndx;
}
byte[] buf_array = HDFNativeData.intToByte(0, DIM_X * DIM_Y, 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 = HDFNativeData.byteToInt(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] == 254);
}
@Test
public void testH5Diterate()
{
final int SPACE_RANK = 2;
final int SPACE_FILL = 254;
class H5D_iter_data implements H5D_iterate_t {
public int fill_value; /* The fill value to check */
public long fill_curr_coord; /* Current coordinate to examine */
public long[] fill_coords; /* Pointer to selection's coordinates */
}
H5D_iterate_t iter_data = new H5D_iter_data();
class H5D_iter_callback implements H5D_iterate_cb {
public int callback(byte[] elem_buf, long elem_id, int ndim, long[] point, H5D_iterate_t op_data)
{
// Check value in current buffer location
int element = HDFNativeData.byteToInt(elem_buf, 0);
if (element != ((H5D_iter_data)op_data).fill_value)
return -1;
// Check number of dimensions
if (ndim != SPACE_RANK)
return (-1);
// Check Coordinates
long[] fill_coords = new long[2];
fill_coords[0] =
((H5D_iter_data)op_data).fill_coords[(int)(2 * ((H5D_iter_data)op_data).fill_curr_coord)];
fill_coords[1] = ((H5D_iter_data)op_data)
.fill_coords[(int)(2 * ((H5D_iter_data)op_data).fill_curr_coord) + 1];
((H5D_iter_data)op_data).fill_curr_coord++;
if (fill_coords[0] != point[0])
return (-1);
if (fill_coords[1] != point[1])
return (-1);
return (0);
}
}
int[] buf_data = new int[DIM_X * DIM_Y];
byte[] fill_value = HDFNativeData.intToByte(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] = indx * jndx - jndx;
}
byte[] buf_array = HDFNativeData.intToByte(0, DIM_X * DIM_Y, 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);
}
@Test
public void testH5Diterate_write()
{
final int SPACE_RANK = 2;
final int SPACE_FILL = 254;
class H5D_iter_data implements H5D_iterate_t {
public int fill_value; /* The fill value to check */
public long fill_curr_coord; /* Current coordinate to examine */
public long[] fill_coords; /* Pointer to selection's coordinates */
}
H5D_iterate_t iter_data = new H5D_iter_data();
class H5D_iter_callback implements H5D_iterate_cb {
public int callback(byte[] elem_buf, long elem_id, int ndim, long[] point, H5D_iterate_t op_data)
{
// Check value in current buffer location
int element = HDFNativeData.byteToInt(elem_buf, 0);
if (element != ((H5D_iter_data)op_data).fill_value)
return -1;
// Check number of dimensions
if (ndim != SPACE_RANK)
return (-1);
// Check Coordinates
long[] fill_coords = new long[2];
fill_coords[0] =
((H5D_iter_data)op_data).fill_coords[(int)(2 * ((H5D_iter_data)op_data).fill_curr_coord)];
fill_coords[1] = ((H5D_iter_data)op_data)
.fill_coords[(int)(2 * ((H5D_iter_data)op_data).fill_curr_coord) + 1];
((H5D_iter_data)op_data).fill_curr_coord++;
if (fill_coords[0] != point[0])
return (-1);
if (fill_coords[1] != point[1])
return (-1);
element -= 128;
byte[] new_elembuf = HDFNativeData.intToByte(element);
elem_buf[0] = new_elembuf[0];
elem_buf[1] = new_elembuf[1];
elem_buf[2] = new_elembuf[2];
elem_buf[3] = new_elembuf[3];
return (0);
}
}
int[] buf_data = new int[DIM_X * DIM_Y];
byte[] fill_value = HDFNativeData.intToByte(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] = indx * jndx - jndx;
}
byte[] buf_array = HDFNativeData.intToByte(0, DIM_X * DIM_Y, 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 = HDFNativeData.byteToInt(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] == 126);
}
@Ignore
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
_createVLStrDataset("dset", HDF5Constants.H5P_DEFAULT);
try {
if ((H5did >= 0) && (H5dtid >= 0))
H5.H5DwriteVL(H5did, H5dtid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, 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);
}
@Ignore
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", "!!!"};
String[] str_rdata = new String[DIM_X * DIM_Y];
_createVLStrDataset("dset", HDF5Constants.H5P_DEFAULT);
try {
if ((H5did >= 0) && (H5dtid >= 0))
H5.H5DwriteVL(H5did, H5dtid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, str_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, str_rdata);
}
catch (Exception e) {
e.printStackTrace();
}
for (int v = 0; v < DIM_X * DIM_Y; v++)
assertTrue("testH5Dvlen_write_read " + str_wdata[v] + " == " + str_rdata[v],
str_wdata[v] == str_wdata[v]);
}
@Test
public void testH5DVLwr()
{
String dset_int_name = "VLIntdata";
String dset_dbl_name = "VLDbldata";
long dset_int_id = HDF5Constants.H5I_INVALID_HID;
long dset_dbl_id = HDF5Constants.H5I_INVALID_HID;
long dtype_int_id = HDF5Constants.H5I_INVALID_HID;
long dtype_dbl_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {4};
long lsize = 1;
ArrayList[] vl_int_data = new ArrayList[4];
ArrayList[] vl_dbl_data = new ArrayList[4];
try {
// Write Integer data
vl_int_data[0] = new ArrayList<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) {
}
}
}
/*
* Reading or writing a dataset whose memory type is an array of a fixed base type
* must not accumulate open datatype IDs. Write and read such a dataset repeatedly
* and verify the library's open-datatype count is unchanged.
*/
@Test
public void testH5DArray_datatype_ids_stable() throws Throwable
{
String dset_name = "ArrayIntData";
long dtype_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long dset_id = HDF5Constants.H5I_INVALID_HID;
long[] arr_dims = {3};
final int NITER = 50;
int[] wbuf = {10, 20, 30};
int[] rbuf = new int[3];
try {
dtype_id = H5.H5Tarray_create(HDF5Constants.H5T_NATIVE_INT, 1, arr_dims);
assertTrue("testH5DArray_datatype_ids_stable.H5Tarray_create: ", dtype_id >= 0);
dspace_id = H5.H5Screate(HDF5Constants.H5S_SCALAR);
assertTrue("testH5DArray_datatype_ids_stable.H5Screate: ", dspace_id >= 0);
dset_id = H5.H5Dcreate(H5fid, dset_name, dtype_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DArray_datatype_ids_stable.H5Dcreate: ", dset_id >= 0);
/*
* The leaked IDs are transient datatypes (from H5Tget_super), which are not
* attached to any file, so they are only visible through the H5F_OBJ_ALL path
* that walks the global datatype ID list. Scoping the count to a single file id
* would miss them entirely.
*/
long before = H5.H5Fget_obj_count(HDF5Constants.H5F_OBJ_ALL, HDF5Constants.H5F_OBJ_DATATYPE);
assertTrue("testH5DArray_datatype_ids_stable.H5Fget_obj_count(before): ", before >= 0);
for (int i = 0; i < NITER; i++) {
H5.H5Dwrite(dset_id, dtype_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, wbuf);
H5.H5Dread(dset_id, dtype_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, rbuf);
}
long after = H5.H5Fget_obj_count(HDF5Constants.H5F_OBJ_ALL, HDF5Constants.H5F_OBJ_DATATYPE);
assertTrue("testH5DArray_datatype_ids_stable.H5Fget_obj_count(after): ", after >= 0);
assertEquals("testH5DArray_datatype_ids_stable: open datatype count changed after " + NITER +
" write/read cycles on an array datatype",
before, after);
}
finally {
if (dset_id >= 0)
try {
H5.H5Dclose(dset_id);
}
catch (Exception ex) {
}
if (dtype_id >= 0)
try {
H5.H5Tclose(dtype_id);
}
catch (Exception ex) {
}
if (dspace_id >= 0)
try {
H5.H5Sclose(dspace_id);
}
catch (Exception ex) {
}
}
}
/*
* The object-tree read/write path derives a base datatype from the memory type with
* H5Tget_super() for the variable-length, array and complex classes. Those transient
* IDs are only visible through the H5F_OBJ_ALL path that walks the global datatype ID
* list.
*/
private long openDatatypeCount() throws Throwable
{
long count = H5.H5Fget_obj_count(HDF5Constants.H5F_OBJ_ALL, HDF5Constants.H5F_OBJ_DATATYPE);
assertTrue("H5Fget_obj_count: ", count >= 0);
return count;
}
/*
* Reading or writing a dataset of a variable-length type through the object-tree path
* must not accumulate open datatype IDs.
*/
@Test
public void testH5DVL_datatype_ids_stable() throws Throwable
{
long dtype_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long dset_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {2};
final int NITER = 50;
ArrayList[] wbuf = new ArrayList[2];
try {
wbuf[0] = new ArrayList<Integer>(Arrays.asList(1));
wbuf[1] = new ArrayList<Integer>(Arrays.asList(2, 3));
dtype_id = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_INT);
assertTrue("testH5DVL_datatype_ids_stable.H5Tvlen_create: ", dtype_id >= 0);
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue("testH5DVL_datatype_ids_stable.H5Screate_simple: ", dspace_id >= 0);
dset_id = H5.H5Dcreate(H5fid, "VLIntIdCount", dtype_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DVL_datatype_ids_stable.H5Dcreate: ", dset_id >= 0);
long before = openDatatypeCount();
for (int i = 0; i < NITER; i++) {
H5.H5DwriteVL(dset_id, dtype_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, wbuf);
ArrayList[] rbuf = new ArrayList[2];
H5.H5DreadVL(dset_id, dtype_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, rbuf);
assertEquals("testH5DVL_datatype_ids_stable: row 0", Integer.valueOf(1), rbuf[0].get(0));
}
assertEquals("testH5DVL_datatype_ids_stable: open datatype count changed after " + NITER +
" write/read cycles on a variable-length datatype",
before, openDatatypeCount());
}
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 (dtype_id >= 0)
try {
H5.H5Tclose(dtype_id);
}
catch (Exception ex) {
}
}
}
/*
* Reading or writing a dataset of an array type through the object-tree path must not
* accumulate open datatype IDs.
*/
@Test
public void testH5DArrayVL_datatype_ids_stable() throws Throwable
{
long dtype_id = HDF5Constants.H5I_INVALID_HID;
long dspace_id = HDF5Constants.H5I_INVALID_HID;
long dset_id = HDF5Constants.H5I_INVALID_HID;
long[] dims = {2};
long[] arr_dims = {3};
final int NITER = 50;
ArrayList[] wbuf = new ArrayList[2];
try {
wbuf[0] = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
wbuf[1] = new ArrayList<Integer>(Arrays.asList(4, 5, 6));
dtype_id = H5.H5Tarray_create(HDF5Constants.H5T_NATIVE_INT, 1, arr_dims);
assertTrue("testH5DArrayVL_datatype_ids_stable.H5Tarray_create: ", dtype_id >= 0);
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue("testH5DArrayVL_datatype_ids_stable.H5Screate_simple: ", dspace_id >= 0);
dset_id = H5.H5Dcreate(H5fid, "ArrayIntIdCount", dtype_id, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5DArrayVL_datatype_ids_stable.H5Dcreate: ", dset_id >= 0);
long before = openDatatypeCount();
for (int i = 0; i < NITER; i++) {
H5.H5DwriteVL(dset_id, dtype_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, wbuf);
ArrayList[] rbuf = new ArrayList[2];
H5.H5DreadVL(dset_id, dtype_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, rbuf);
assertEquals("testH5DArrayVL_datatype_ids_stable: row 0", Integer.valueOf(1), rbuf[0].get(0));
}
assertEquals("testH5DArrayVL_datatype_ids_stable: open datatype count changed after " + NITER +
" write/read cycles on an array datatype",
before, openDatatypeCount());
}
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 (dtype_id >= 0)
try {
H5.H5Tclose(dtype_id);
}
catch (Exception ex) {
}
}
}
/*
* A compound member that is itself a variable-length type is converted by the
* per-element helpers. Reading or writing such a dataset must not accumulate
* open datatype IDs.
*/
@Test
public void testH5Dcompound_of_vlen_datatype_ids_stable() throws Throwable
{
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;
long[] dims = {2};
final int NITER = 50;
ArrayList[] wbuf = new ArrayList[2];
try {
long intSize = H5.H5Tget_size(HDF5Constants.H5T_NATIVE_INT);
vlen_tid = H5.H5Tvlen_create(HDF5Constants.H5T_NATIVE_INT);
assertTrue("testH5Dcompound_of_vlen_datatype_ids_stable.H5Tvlen_create: ", vlen_tid >= 0);
cmpd_tid = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND, intSize + H5.H5Tget_size(vlen_tid));
assertTrue("testH5Dcompound_of_vlen_datatype_ids_stable.H5Tcreate: ", cmpd_tid >= 0);
H5.H5Tinsert(cmpd_tid, "A", 0, HDF5Constants.H5T_NATIVE_INT);
H5.H5Tinsert(cmpd_tid, "B", intSize, vlen_tid);
dspace_id = H5.H5Screate_simple(1, dims, null);
assertTrue("testH5Dcompound_of_vlen_datatype_ids_stable.H5Screate_simple: ", dspace_id >= 0);
dset_id = H5.H5Dcreate(H5fid, "CmpdVLIdCount", cmpd_tid, dspace_id, HDF5Constants.H5P_DEFAULT,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
assertTrue("testH5Dcompound_of_vlen_datatype_ids_stable.H5Dcreate: ", dset_id >= 0);
for (int r = 0; r < dims[0]; r++) {
ArrayList<Object> row = new ArrayList<>();
row.add(Integer.valueOf(r));
row.add(new ArrayList<Integer>(Arrays.asList(r + 1, r + 2)));
wbuf[r] = row;
}
long before = openDatatypeCount();
for (int i = 0; i < NITER; i++) {
H5.H5DwriteVL(dset_id, cmpd_tid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, wbuf);
ArrayList[] rbuf = new ArrayList[2];
H5.H5DreadVL(dset_id, cmpd_tid, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, rbuf);
assertEquals("testH5Dcompound_of_vlen_datatype_ids_stable: row 0 member A",
Integer.valueOf(0), rbuf[0].get(0));
}
assertEquals("testH5Dcompound_of_vlen_datatype_ids_stable: open datatype count changed after " +
NITER + " write/read cycles on a compound with a variable-length member",
before, openDatatypeCount());
}
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 (cmpd_tid >= 0)
try {
H5.H5Tclose(cmpd_tid);
}
catch (Exception ex) {
}
if (vlen_tid >= 0)
try {
H5.H5Tclose(vlen_tid);
}
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)));
}
/*
* 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) {
}
}
}
@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[1];
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);
// 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) {
}
}
}
/*
* 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) {
}
}
}
}