diff --git a/pom.xml b/pom.xml index ee1886b..9254400 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,7 @@ --enable-native-access=ALL-UNNAMED -H:+ForeignAPISupport -H:+UnlockExperimentalVMOptions + --enable-preview @@ -64,6 +65,13 @@ org.springframework.boot spring-boot-maven-plugin + + + + --enable-preview + + + diff --git a/src/main/java/com/example/demo/DemoApplication.java b/src/main/java/com/example/demo/DemoApplication.java index 576f696..6d12bbc 100644 --- a/src/main/java/com/example/demo/DemoApplication.java +++ b/src/main/java/com/example/demo/DemoApplication.java @@ -10,8 +10,14 @@ import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.Linker; import java.lang.foreign.SymbolLookup; +import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import java.util.stream.Gatherer; +import java.util.stream.Stream; import static java.lang.foreign.ValueLayout.ADDRESS; import static java.lang.foreign.ValueLayout.JAVA_INT; @@ -19,7 +25,7 @@ @SpringBootApplication public class DemoApplication { - public static void main(String[] args) throws Throwable { + public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @@ -49,12 +55,61 @@ interface LanguageDemonstrationRunner { void run() throws Throwable; } +@Component +class Gatherers implements LanguageDemonstrationRunner { + + // viktor klang! the legend of klang continues! + //https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/util/stream/Gatherer.html + private static Gatherer scan( + Supplier initial, + BiFunction scanner) { + + class State { + R current = initial.get(); + } + + return Gatherer.ofSequential( + State::new, + Gatherer.Integrator.ofGreedy((state, element, downstream) -> { + state.current = scanner.apply(state.current, element); + return downstream.push(state.current); + }) + ); + } + + @Override + public void run() { + + var listOfNumberStrings = Stream + .of(1, 2, 3, 4, 5, 6, 7, 8, 9) + .gather(scan(() -> "", (string, number) -> string + number) + .andThen(java.util.stream.Gatherers.mapConcurrent(10, + s -> s.toUpperCase(Locale.ROOT))) + ) + .toList(); + + System.out.println( listOfNumberStrings); + + } +} + +@Component +class StringTemplates implements LanguageDemonstrationRunner { + + @Override + public void run() throws Throwable { + var name = "josh"; + System.out.println(STR."name: \{name.toUpperCase()}"); + } +} + @Component class JExtractFfi implements LanguageDemonstrationRunner { @Override public void run() throws Throwable { + } } @@ -62,33 +117,27 @@ public void run() throws Throwable { @Component class ManualFfi implements LanguageDemonstrationRunner { - public static final FunctionDescriptor PRINTF_FUNCTION_DESCRIPTOR = + static final FunctionDescriptor PRINTF_FUNCTION_DESCRIPTOR = FunctionDescriptor.of(JAVA_INT, ADDRESS); - private final SymbolLookup symbolLookup; ManualFfi(SymbolLookup symbolLookup) { this.symbolLookup = symbolLookup; } - private void manualFfi(String greetings) throws Throwable { + @Override + public void run() throws Throwable { var symbolName = "printf"; var nativeLinker = Linker.nativeLinker(); - var methodHandle = this.symbolLookup .find(symbolName) .map(symbolSegment -> nativeLinker .downcallHandle(symbolSegment, PRINTF_FUNCTION_DESCRIPTOR)) .orElse(null); try (var arena = Arena.ofConfined()) { - var cString = arena.allocateFrom(greetings); + var cString = arena.allocateFrom("hello, manual FFI!"); Objects.requireNonNull(methodHandle).invoke(cString); } } - - @Override - public void run() throws Throwable { - manualFfi("hello, manual FFI!"); - } } \ No newline at end of file