mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
Add Java bindings for H5Pmodify_filter_by_idx
Implements the two overloads specified in RFC-HDFG-2026-001
sec:modify-bindings -- one taking a String, one an int[] -- mirroring
the existing H5Pappend_filter overloads.
Both Java binding paths are covered, since the tree maintains two:
- JNI (java/src-jni): two private native methods dispatched from the
public overloads, plus the JNI implementations and declarations in
h5pDCPLImp.c/.h, following the H5Pappend_filter_str/_raw pattern
exactly.
- Panama/FFM (java/hdf): the H5Z_params_t struct is built directly in
an Arena and passed to the generated org.hdfgroup.javahdf5.hdf5_h
downcall, as the append string form already does. Unlike the append
case the cd_values form cannot delegate to H5Pmodify_filter, which
addresses an entry by filter ID and resolves to the first match
rather than by index, so it constructs the struct explicitly. The
generated binding is produced by jextract from the public headers,
so it picks up the new declaration automatically.
Adds testH5Pmodify_filter_by_idx_string and
testH5Pmodify_filter_by_idx_cdvalues to TestH5Z.java and updates the
JUnit golden file. Placement and the test count were derived from
@FixMethodOrder(MethodSorters.NAME_ASCENDING) rather than guessed, and
the file's surrounding format is unchanged.
Not compile-verified locally: this configuration has HDF5_BUILD_JAVA
OFF and the machine has a JRE but no JDK (no javac) and no jextract, so
nothing under java/ can be built here. The C library still builds clean
and the full C/Fortran suite is unchanged. What was checked statically:
the JNI symbol names against the mangling rule (underscores in the Java
method name become _1) and against the existing append pair; the
H5Z_params_t offsets (int type at 0, union at 8, cd_nelmts at 8,
cd_values at 16, 24 bytes total on 64-bit) and the enum values
(H5Z_PARAMS_CDVALUES 0, H5Z_PARAMS_STRING 1) against H5Zpublic.h; and
the H5Pget_filter call in the new test against the working call in
testH5Pappend_filter_cdvalues. Java CI should be treated as the real
gate.
This commit is contained in:
@@ -12495,6 +12495,111 @@ public class H5 implements java.io.Serializable {
|
||||
return H5Pset_filter(plist_id, filter_id, flags, (long)values.length, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup JH5P
|
||||
*
|
||||
* H5Pmodify_filter_by_idx replaces the configuration of the filter at a pipeline index using a
|
||||
* human-readable key=value parameter string. The entry keeps a stored configuration string.
|
||||
*
|
||||
* @param plist_id
|
||||
* IN: Property list identifier.
|
||||
* @param filter_idx
|
||||
* IN: Zero-based index of the filter in the pipeline.
|
||||
* @param flags
|
||||
* IN: Bit vector specifying certain general properties of the filter.
|
||||
* @param params
|
||||
* IN: Parameter string in "key=value" format, or null for no parameters.
|
||||
*
|
||||
* @return a non-negative value if successful
|
||||
*
|
||||
* @exception HDF5LibraryException
|
||||
* Error from the HDF5 Library.
|
||||
**/
|
||||
public static int H5Pmodify_filter_by_idx(long plist_id, int filter_idx, int flags, String params)
|
||||
throws HDF5LibraryException
|
||||
{
|
||||
if (plist_id < 0)
|
||||
throw new HDF5FunctionArgumentException("Negative property list identifier");
|
||||
|
||||
int retVal = -1;
|
||||
/* H5Z_params_t layout (64-bit): int type(4) + pad(4) + union(16) = 24 bytes */
|
||||
final int H5Z_PARAMS_STRING = 1;
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment str_seg =
|
||||
(params != null && !params.isEmpty()) ? arena.allocateFrom(params) : MemorySegment.NULL;
|
||||
MemorySegment params_struct = arena.allocate(24, 8);
|
||||
params_struct.set(ValueLayout.JAVA_INT, 0, H5Z_PARAMS_STRING);
|
||||
params_struct.set(ValueLayout.ADDRESS, 8, str_seg);
|
||||
retVal = org.hdfgroup.javahdf5.hdf5_h.H5Pmodify_filter_by_idx(plist_id, filter_idx, flags,
|
||||
params_struct);
|
||||
}
|
||||
catch (HDF5LibraryException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw new HDF5LibraryException("H5Pmodify_filter_by_idx failed: " + t.getMessage());
|
||||
}
|
||||
if (retVal < 0)
|
||||
h5libraryError();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup JH5P
|
||||
*
|
||||
* H5Pmodify_filter_by_idx replaces the configuration of the filter at a pipeline index using raw
|
||||
* cd_values parameters. This form clears any stored configuration string on the entry, so
|
||||
* introspection falls back to the filter's get_config reconstruction.
|
||||
*
|
||||
* @param plist_id
|
||||
* IN: Property list identifier.
|
||||
* @param filter_idx
|
||||
* IN: Zero-based index of the filter in the pipeline.
|
||||
* @param flags
|
||||
* IN: Bit vector specifying certain general properties of the filter.
|
||||
* @param cd_values
|
||||
* IN: Auxiliary data for the filter, or null for no parameters.
|
||||
*
|
||||
* @return a non-negative value if successful
|
||||
*
|
||||
* @exception HDF5LibraryException
|
||||
* Error from the HDF5 Library.
|
||||
**/
|
||||
public static int H5Pmodify_filter_by_idx(long plist_id, int filter_idx, int flags, int[] cd_values)
|
||||
throws HDF5LibraryException
|
||||
{
|
||||
if (plist_id < 0)
|
||||
throw new HDF5FunctionArgumentException("Negative property list identifier");
|
||||
|
||||
int retVal = -1;
|
||||
/* Unlike the append case this cannot delegate to H5Pmodify_filter: that
|
||||
* addresses an entry by filter ID and resolves to the first match, whereas
|
||||
* this API addresses by pipeline index. The struct is built explicitly. */
|
||||
final int H5Z_PARAMS_CDVALUES = 0;
|
||||
int[] values = (cd_values != null) ? cd_values : new int[0];
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment vals_seg = (values.length > 0)
|
||||
? arena.allocateFrom(ValueLayout.JAVA_INT, values)
|
||||
: MemorySegment.NULL;
|
||||
MemorySegment params_struct = arena.allocate(24, 8);
|
||||
params_struct.set(ValueLayout.JAVA_INT, 0, H5Z_PARAMS_CDVALUES);
|
||||
/* union { struct { size_t cd_nelmts; const unsigned *cd_values; } raw; ... } */
|
||||
params_struct.set(ValueLayout.JAVA_LONG, 8, (long)values.length);
|
||||
params_struct.set(ValueLayout.ADDRESS, 16, vals_seg);
|
||||
retVal = org.hdfgroup.javahdf5.hdf5_h.H5Pmodify_filter_by_idx(plist_id, filter_idx, flags,
|
||||
params_struct);
|
||||
}
|
||||
catch (HDF5LibraryException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw new HDF5LibraryException("H5Pmodify_filter_by_idx failed: " + t.getMessage());
|
||||
}
|
||||
if (retVal < 0)
|
||||
h5libraryError();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup JH5P
|
||||
*
|
||||
|
||||
@@ -8500,6 +8500,67 @@ public class H5 implements java.io.Serializable {
|
||||
private synchronized static native int H5Pappend_filter_raw(long plist_id, int filter_id, int flags,
|
||||
int[] cd_values) throws HDF5LibraryException;
|
||||
|
||||
/**
|
||||
* @ingroup JH5P
|
||||
*
|
||||
* H5Pmodify_filter_by_idx replaces the configuration of the filter at a pipeline index using a
|
||||
* human-readable key=value parameter string. The entry keeps a stored configuration string.
|
||||
*
|
||||
* @param plist_id
|
||||
* IN: Property list identifier.
|
||||
* @param filter_idx
|
||||
* IN: Zero-based index of the filter in the pipeline.
|
||||
* @param flags
|
||||
* IN: Bit vector specifying general filter properties.
|
||||
* @param params
|
||||
* IN: Parameter string in "key=value" format, or null for no parameters.
|
||||
*
|
||||
* @return a non-negative value if successful
|
||||
*
|
||||
* @exception HDF5LibraryException
|
||||
* Error from the HDF5 Library.
|
||||
**/
|
||||
public synchronized static int H5Pmodify_filter_by_idx(long plist_id, int filter_idx, int flags,
|
||||
String params) throws HDF5LibraryException
|
||||
{
|
||||
return H5Pmodify_filter_by_idx_str(plist_id, filter_idx, flags, params);
|
||||
}
|
||||
|
||||
private synchronized static native int H5Pmodify_filter_by_idx_str(long plist_id, int filter_idx,
|
||||
int flags, String params)
|
||||
throws HDF5LibraryException;
|
||||
|
||||
/**
|
||||
* @ingroup JH5P
|
||||
*
|
||||
* H5Pmodify_filter_by_idx replaces the configuration of the filter at a pipeline index using raw
|
||||
* cd_values parameters. This form clears any stored configuration string on the entry, so
|
||||
* introspection falls back to the filter's get_config reconstruction.
|
||||
*
|
||||
* @param plist_id
|
||||
* IN: Property list identifier.
|
||||
* @param filter_idx
|
||||
* IN: Zero-based index of the filter in the pipeline.
|
||||
* @param flags
|
||||
* IN: Bit vector specifying general filter properties.
|
||||
* @param cd_values
|
||||
* IN: Auxiliary data for the filter, or null for no parameters.
|
||||
*
|
||||
* @return a non-negative value if successful
|
||||
*
|
||||
* @exception HDF5LibraryException
|
||||
* Error from the HDF5 Library.
|
||||
**/
|
||||
public synchronized static int H5Pmodify_filter_by_idx(long plist_id, int filter_idx, int flags,
|
||||
int[] cd_values) throws HDF5LibraryException
|
||||
{
|
||||
return H5Pmodify_filter_by_idx_raw(plist_id, filter_idx, flags, cd_values);
|
||||
}
|
||||
|
||||
private synchronized static native int H5Pmodify_filter_by_idx_raw(long plist_id, int filter_idx,
|
||||
int flags, int[] cd_values)
|
||||
throws HDF5LibraryException;
|
||||
|
||||
/**
|
||||
* @ingroup JH5P
|
||||
*
|
||||
|
||||
@@ -1458,6 +1458,78 @@ done:
|
||||
return (jint)status;
|
||||
} /* end Java_hdf_hdf5lib_H5_H5Pappend_1filter_1raw */
|
||||
|
||||
/*
|
||||
* Class: hdf_hdf5lib_H5
|
||||
* Method: H5Pmodify_filter_by_idx (string form)
|
||||
* Signature: (JIILjava/lang/String;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_hdf_hdf5lib_H5_H5Pmodify_1filter_1by_1idx_1str(JNIEnv *env, jclass clss, jlong plist_id,
|
||||
jint filter_idx, jint flags, jstring params)
|
||||
{
|
||||
H5Z_params_t p;
|
||||
const char *c_params = NULL;
|
||||
jboolean isCopy;
|
||||
herr_t status = FAIL;
|
||||
|
||||
UNUSED(clss);
|
||||
|
||||
if (params)
|
||||
PIN_JAVA_STRING(ENVONLY, params, c_params, &isCopy,
|
||||
"H5Pmodify_filter_by_idx: params string not pinned");
|
||||
|
||||
p.type = H5Z_PARAMS_STRING;
|
||||
p.u.str = c_params;
|
||||
|
||||
if ((status = H5Pmodify_filter_by_idx((hid_t)plist_id, (unsigned)filter_idx, (unsigned)flags, &p)) < 0)
|
||||
H5_LIBRARY_ERROR(ENVONLY);
|
||||
|
||||
done:
|
||||
if (c_params)
|
||||
UNPIN_JAVA_STRING(ENVONLY, params, c_params);
|
||||
|
||||
return (jint)status;
|
||||
} /* end Java_hdf_hdf5lib_H5_H5Pmodify_1filter_1by_1idx_1str */
|
||||
|
||||
/*
|
||||
* Class: hdf_hdf5lib_H5
|
||||
* Method: H5Pmodify_filter_by_idx (raw cd_values form)
|
||||
* Signature: (JII[I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_hdf_hdf5lib_H5_H5Pmodify_1filter_1by_1idx_1raw(JNIEnv *env, jclass clss, jlong plist_id,
|
||||
jint filter_idx, jint flags, jintArray cd_values)
|
||||
{
|
||||
H5Z_params_t p;
|
||||
jint *c_cd_values = NULL;
|
||||
jboolean isCopy;
|
||||
herr_t status = FAIL;
|
||||
jsize cd_nelmts = 0;
|
||||
|
||||
UNUSED(clss);
|
||||
|
||||
if (cd_values) {
|
||||
cd_nelmts = ENVPTR->GetArrayLength(ENVONLY, cd_values);
|
||||
if (cd_nelmts < 0)
|
||||
H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pmodify_filter_by_idx: cd_values array length < 0");
|
||||
PIN_INT_ARRAY(ENVONLY, cd_values, c_cd_values, &isCopy,
|
||||
"H5Pmodify_filter_by_idx: cd_values not pinned");
|
||||
}
|
||||
|
||||
p.type = H5Z_PARAMS_CDVALUES;
|
||||
p.u.raw.cd_nelmts = (size_t)cd_nelmts;
|
||||
p.u.raw.cd_values = (const unsigned *)c_cd_values;
|
||||
|
||||
if ((status = H5Pmodify_filter_by_idx((hid_t)plist_id, (unsigned)filter_idx, (unsigned)flags, &p)) < 0)
|
||||
H5_LIBRARY_ERROR(ENVONLY);
|
||||
|
||||
done:
|
||||
if (c_cd_values)
|
||||
UNPIN_INT_ARRAY(ENVONLY, cd_values, c_cd_values, JNI_ABORT);
|
||||
|
||||
return (jint)status;
|
||||
} /* end Java_hdf_hdf5lib_H5_H5Pmodify_1filter_1by_1idx_1raw */
|
||||
|
||||
/*
|
||||
* Class: hdf_hdf5lib_H5
|
||||
* Method: H5Pget_filter_params_by_idx
|
||||
|
||||
@@ -155,6 +155,22 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Pappend_1filter_1str(JNIEnv *, jcla
|
||||
JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Pappend_1filter_1raw(JNIEnv *, jclass, jlong, jint, jint,
|
||||
jintArray);
|
||||
|
||||
/*
|
||||
* Class: hdf_hdf5lib_H5
|
||||
* Method: H5Pmodify_filter_by_idx (string form)
|
||||
* Signature: (JIILjava/lang/String;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Pmodify_1filter_1by_1idx_1str(JNIEnv *, jclass, jlong, jint,
|
||||
jint, jstring);
|
||||
|
||||
/*
|
||||
* Class: hdf_hdf5lib_H5
|
||||
* Method: H5Pmodify_filter_by_idx (raw cd_values form)
|
||||
* Signature: (JII[I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Pmodify_1filter_1by_1idx_1raw(JNIEnv *, jclass, jlong, jint,
|
||||
jint, jintArray);
|
||||
|
||||
/*
|
||||
* Class: hdf_hdf5lib_H5
|
||||
* Method: H5Pget_filter_params_by_idx
|
||||
|
||||
@@ -243,6 +243,92 @@ public class TestH5Z {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testH5Pmodify_filter_by_idx_string()
|
||||
{
|
||||
long dcpl_id = HDF5Constants.H5I_INVALID_HID;
|
||||
try {
|
||||
dcpl_id = H5.H5Pcreate(HDF5Constants.H5P_DATASET_CREATE);
|
||||
assertTrue("H5Pcreate", dcpl_id >= 0);
|
||||
|
||||
if (1 == H5.H5Zfilter_avail(HDF5Constants.H5Z_FILTER_DEFLATE)) {
|
||||
int ret = H5.H5Pappend_filter(dcpl_id, HDF5Constants.H5Z_FILTER_DEFLATE, 0, "level=1");
|
||||
assertTrue("H5Pappend_filter (string, deflate)", ret >= 0);
|
||||
|
||||
// Replace the configuration in place; position and ID are unchanged.
|
||||
ret = H5.H5Pmodify_filter_by_idx(dcpl_id, 0, 0, "level=9");
|
||||
assertTrue("H5Pmodify_filter_by_idx (string)", ret >= 0);
|
||||
|
||||
int nfilters = H5.H5Pget_nfilters(dcpl_id);
|
||||
assertEquals("nfilters after H5Pmodify_filter_by_idx", 1, nfilters);
|
||||
|
||||
// The entry keeps a stored string, which reports the new value.
|
||||
String[] params = new String[1];
|
||||
ret = H5.H5Pget_filter_params_by_idx(dcpl_id, 0, params);
|
||||
assertTrue("H5Pget_filter_params_by_idx", ret >= 0);
|
||||
assertNotNull("params[0] is non-null", params[0]);
|
||||
assertTrue("stored string reflects the modify: " + params[0],
|
||||
params[0].contains("level=9"));
|
||||
}
|
||||
}
|
||||
catch (Throwable err) {
|
||||
err.printStackTrace();
|
||||
fail("testH5Pmodify_filter_by_idx_string: " + err);
|
||||
}
|
||||
finally {
|
||||
if (dcpl_id != HDF5Constants.H5I_INVALID_HID)
|
||||
try {
|
||||
H5.H5Pclose(dcpl_id);
|
||||
}
|
||||
catch (Exception e) { /* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testH5Pmodify_filter_by_idx_cdvalues()
|
||||
{
|
||||
long dcpl_id = HDF5Constants.H5I_INVALID_HID;
|
||||
try {
|
||||
dcpl_id = H5.H5Pcreate(HDF5Constants.H5P_DATASET_CREATE);
|
||||
assertTrue("H5Pcreate", dcpl_id >= 0);
|
||||
|
||||
if (1 == H5.H5Zfilter_avail(HDF5Constants.H5Z_FILTER_DEFLATE)) {
|
||||
int ret = H5.H5Pappend_filter(dcpl_id, HDF5Constants.H5Z_FILTER_DEFLATE, 0, "level=1");
|
||||
assertTrue("H5Pappend_filter (string, deflate)", ret >= 0);
|
||||
|
||||
int[] cd_values = new int[] {6};
|
||||
ret = H5.H5Pmodify_filter_by_idx(dcpl_id, 0, 0, cd_values);
|
||||
assertTrue("H5Pmodify_filter_by_idx (cd_values)", ret >= 0);
|
||||
|
||||
int nfilters = H5.H5Pget_nfilters(dcpl_id);
|
||||
assertEquals("nfilters after H5Pmodify_filter_by_idx", 1, nfilters);
|
||||
|
||||
// cd_values were replaced.
|
||||
int[] cd_out = new int[1];
|
||||
int[] flags_out = new int[1];
|
||||
long[] cd_nelmts = new long[] {1};
|
||||
String[] name_out = new String[] {""};
|
||||
int filter_id =
|
||||
H5.H5Pget_filter(dcpl_id, 0, flags_out, cd_nelmts, cd_out, 256, name_out, new int[1]);
|
||||
assertEquals("filter id unchanged by modify", HDF5Constants.H5Z_FILTER_DEFLATE, filter_id);
|
||||
assertEquals("cd_values[0] after modify", 6, cd_out[0]);
|
||||
}
|
||||
}
|
||||
catch (Throwable err) {
|
||||
err.printStackTrace();
|
||||
fail("testH5Pmodify_filter_by_idx_cdvalues: " + err);
|
||||
}
|
||||
finally {
|
||||
if (dcpl_id != HDF5Constants.H5I_INVALID_HID)
|
||||
try {
|
||||
H5.H5Pclose(dcpl_id);
|
||||
}
|
||||
catch (Exception e) { /* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testH5Pget_filter_params_by_idx()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,8 @@ JUnit version 4.13.2
|
||||
.testH5Pappend_filter_cdvalues
|
||||
.testH5Pappend_filter_string
|
||||
.testH5Pget_filter_params_by_idx
|
||||
.testH5Pmodify_filter_by_idx_cdvalues
|
||||
.testH5Pmodify_filter_by_idx_string
|
||||
.testH5Zconfig_get_param_bool
|
||||
.testH5Zconfig_get_param_double
|
||||
.testH5Zconfig_get_param_int
|
||||
@@ -15,5 +17,5 @@ JUnit version 4.13.2
|
||||
|
||||
Time: XXXX
|
||||
|
||||
OK (13 tests)
|
||||
OK (15 tests)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user