mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
FFM build requires Java 25, Jextract 25. Generates FFM bindings during configure. JNI is default when the requirements are not met or can be forced. Presets added for maven and FFM - JNI is default selection. Enhanced Maven options will work with either JNI or FFM New Workflows for testing and maven uploads. Extensive documentation changes for java.
188 lines
7.1 KiB
Java
188 lines
7.1 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. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/************************************************************
|
|
This example shows a way to recursively traverse the file
|
|
using H5Literate. The method shown here guarantees that
|
|
the recursion will not enter an infinite loop, but does
|
|
not prevent objects from being visited more than once.
|
|
The program prints the directory structure of the file
|
|
specified in FILE. The default file used by this example
|
|
implements the structure described in the User's Guide,
|
|
chapter 4, figure 26.
|
|
************************************************************/
|
|
|
|
import static org.hdfgroup.javahdf5.hdf5_h.*;
|
|
|
|
import java.lang.foreign.Arena;
|
|
import java.lang.foreign.MemorySegment;
|
|
import java.lang.foreign.ValueLayout;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import hdf.hdf5lib.structs.H5O_token_t;
|
|
|
|
import org.hdfgroup.javahdf5.*;
|
|
|
|
public class H5Ex_G_Traverse {
|
|
|
|
private static String FILENAME = "groups/h5ex_g_traverse.h5";
|
|
|
|
// Operator data structure for iteration
|
|
static class OpData {
|
|
int recurs; // Recursion level
|
|
OpData prev; // Previous operator data
|
|
H5O_token_t obj_token; // Object token
|
|
}
|
|
|
|
private static void OpenGroup(Arena arena)
|
|
{
|
|
long file_id = H5I_INVALID_HID();
|
|
|
|
try {
|
|
// Open file
|
|
file_id = H5Fopen(arena.allocateFrom(FILENAME), H5F_ACC_RDONLY(), H5P_DEFAULT());
|
|
|
|
if (file_id >= 0) {
|
|
// Get info for root group
|
|
MemorySegment root_info = arena.allocate(H5O_info2_t.sizeof());
|
|
H5Oget_info3(file_id, root_info, H5O_INFO_ALL());
|
|
|
|
// Initialize operator data
|
|
OpData od = new OpData();
|
|
od.recurs = 0;
|
|
od.prev = null;
|
|
od.obj_token = new H5O_token_t(H5O_info2_t.token(root_info));
|
|
|
|
// Print root group and begin iteration
|
|
System.out.println("/ {");
|
|
|
|
// Create and iterate
|
|
iterateGroup(arena, file_id, od);
|
|
|
|
System.out.println("}");
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
finally {
|
|
// Close and release resources
|
|
try {
|
|
if (file_id >= 0)
|
|
H5Fclose(file_id);
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void iterateGroup(Arena arena, long group_id, OpData od)
|
|
{
|
|
// Create callback for H5Literate
|
|
H5L_iterate2_t.Function link_callback =
|
|
(long group, MemorySegment name, MemorySegment info, MemorySegment op_data) ->
|
|
{
|
|
String link_name = name.getString(0);
|
|
int spaces = 2 * (od.recurs + 1); // Indentation
|
|
|
|
try {
|
|
// Get object info
|
|
MemorySegment obj_info = arena.allocate(H5O_info2_t.sizeof());
|
|
int ret = H5Oget_info_by_name3(group, name, obj_info, H5O_INFO_ALL(), H5P_DEFAULT());
|
|
|
|
if (ret >= 0) {
|
|
int obj_type = H5O_info2_t.type(obj_info);
|
|
H5O_token_t obj_token = new H5O_token_t(H5O_info2_t.token(obj_info));
|
|
|
|
// Print indentation
|
|
for (int i = 0; i < spaces; i++)
|
|
System.out.print(" ");
|
|
|
|
if (obj_type == H5O_TYPE_GROUP()) {
|
|
System.out.println("Group: " + link_name + " {");
|
|
|
|
// Check for loops
|
|
if (groupCheck(od, obj_token)) {
|
|
for (int i = 0; i < spaces; i++)
|
|
System.out.print(" ");
|
|
System.out.println(" Warning: Loop detected!");
|
|
}
|
|
else {
|
|
// Create new operator data for recursion
|
|
OpData nextod = new OpData();
|
|
nextod.recurs = od.recurs + 1;
|
|
nextod.prev = od;
|
|
nextod.obj_token = obj_token;
|
|
|
|
// Recurse into group
|
|
long subgroup_id = H5Gopen2(group, name, H5P_DEFAULT());
|
|
if (subgroup_id >= 0) {
|
|
try {
|
|
iterateGroup(arena, subgroup_id, nextod);
|
|
}
|
|
finally {
|
|
H5Gclose(subgroup_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < spaces; i++)
|
|
System.out.print(" ");
|
|
System.out.println("}");
|
|
}
|
|
else if (obj_type == H5O_TYPE_DATASET()) {
|
|
System.out.println("Dataset: " + link_name);
|
|
}
|
|
else if (obj_type == H5O_TYPE_NAMED_DATATYPE()) {
|
|
System.out.println("Datatype: " + link_name);
|
|
}
|
|
else {
|
|
System.out.println("Unknown: " + link_name);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return 0; // Continue iteration
|
|
};
|
|
|
|
// Allocate upcall stub
|
|
MemorySegment link_callback_stub = H5L_iterate2_t.allocate(link_callback, arena);
|
|
|
|
// Iterate over links in group
|
|
H5Literate2(group_id, H5_INDEX_NAME(), H5_ITER_NATIVE(), MemorySegment.NULL, link_callback_stub,
|
|
MemorySegment.NULL);
|
|
}
|
|
|
|
// Check if we've already visited this object token (loop detection)
|
|
private static boolean groupCheck(OpData od, H5O_token_t target_token)
|
|
{
|
|
if (od.obj_token.equals(target_token))
|
|
return true; // Object tokens match
|
|
else if (od.recurs == 0)
|
|
return false; // Root group reached with no matches
|
|
else
|
|
return groupCheck(od.prev, target_token); // Recursively examine the next node
|
|
}
|
|
|
|
public static void main(String[] args)
|
|
{
|
|
try (Arena arena = Arena.ofConfined()) {
|
|
H5Ex_G_Traverse.OpenGroup(arena);
|
|
}
|
|
}
|
|
}
|