public java.util.stream.Stream<{{ item_type }}> {{ method_name }}(final {{ request_type }} {{ request_param }}) throws {{ exception_class }} {
java.util.Objects.requireNonNull({{ request_param }}, "{{ request_param }} must not be null");
final MemorySegment streamHandle;
try (var arena = Arena.ofShared()) {
String requestJson = STREAM_MAPPER.writeValueAsString({{ request_param }});
var cRequestJson = arena.allocateFrom(requestJson);
MemorySegment requestPtr = (MemorySegment) NativeLib.{{ req_from_json }}.invoke(cRequestJson);
if (requestPtr.equals(MemorySegment.NULL)) {
checkLastFfiError();
throw new {{ exception_class }}("{{ method_name }}: failed to marshal request", (Throwable) null);
}
Throwable startFailure = null;
try (HandleLease handleLease = borrowHandle()) {
streamHandle = (MemorySegment) NativeLib.{{ start_handle }}.invoke(handleLease.handle(), requestPtr);
if (streamHandle == null || streamHandle.equals(MemorySegment.NULL)) {
checkLastFfiError();
throw new {{ exception_class }}("{{ method_name }}: stream handle was null", (Throwable) null);
}
} catch (Throwable failure) {
startFailure = failure;
throw failure;
} finally {
try {
NativeLib.{{ req_free }}.invoke(requestPtr);
} catch (Throwable cleanupFailure) {
if (startFailure != null) startFailure.addSuppressed(cleanupFailure);
else throw cleanupFailure;
}
}
} catch (Throwable e) {
if (e instanceof {{ exception_class }} ex) { throw ex; }
throw new {{ exception_class }}("{{ method_name }}: failed to start stream", e);
}
{{ iterator_class }} iterator = new {{ iterator_class }}(streamHandle);
return java.util.stream.StreamSupport.stream(
java.util.Spliterators.spliteratorUnknownSize(
iterator,
java.util.Spliterator.ORDERED | java.util.Spliterator.NONNULL
),
false
).onClose(iterator::close);
}
{% include "streaming_iterator_class.jinja" %}