{% if has_doc %}
/// <summary>
{% for line in doc_lines %}
/// {{ line }}
{% endfor %}
/// </summary>
{% else %}
/// <summary>
/// Streaming variant of {{ method_name }}. Returns chunks as an asynchronous sequence.
/// </summary>
{% endif %}
public async IAsyncEnumerable<{{ item_type }}> {{ method_name }}(
{{ request_type }} {{ request_param }},
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var {{ request_param }}Json = JsonSerializer.Serialize({{ request_param }}, JsonSerializationOptions);
var {{ request_param }}Handle = NativeMethods.{{ request_from_json }}({{ request_param }}Json);
if ({{ request_param }}Handle == IntPtr.Zero)
{
var ec = NativeMethods.LastErrorCode();
var ctxPtr = NativeMethods.LastErrorContext();
var msg = global::System.Runtime.InteropServices.Marshal.PtrToStringUTF8(ctxPtr) ?? "{{ request_from_json }} failed";
throw new {{ exception_name }}(ec, msg);
}
var streamHandle = NativeMethods.{{ start_native }}(Handle, {{ request_param }}Handle);
if (streamHandle == IntPtr.Zero)
{
NativeMethods.{{ request_free }}({{ request_param }}Handle);
var ec = NativeMethods.LastErrorCode();
var ctxPtr = NativeMethods.LastErrorContext();
var msg = global::System.Runtime.InteropServices.Marshal.PtrToStringUTF8(ctxPtr) ?? "Unknown error";
throw new {{ exception_name }}(ec, msg);
}
try
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
var chunkPtr = NativeMethods.{{ next_native }}(streamHandle);
if (chunkPtr == IntPtr.Zero)
{
var ec = NativeMethods.LastErrorCode();
if (ec != 0)
{
var ctxPtr = NativeMethods.LastErrorContext();
var msg = global::System.Runtime.InteropServices.Marshal.PtrToStringUTF8(ctxPtr) ?? "Unknown error";
throw new {{ exception_name }}(ec, msg);
}
yield break;
}
var jsonPtr = NativeMethods.{{ item_to_json }}(chunkPtr);
var json = global::System.Runtime.InteropServices.Marshal.PtrToStringUTF8(jsonPtr);
NativeMethods.FreeString(jsonPtr);
NativeMethods.{{ item_free }}(chunkPtr);
var chunk = JsonSerializer.Deserialize<{{ item_type }}>(json ?? "null", JsonOptions)!;
yield return chunk;
await Task.Yield();
}
}
finally
{
NativeMethods.{{ free_native }}(streamHandle);
NativeMethods.{{ request_free }}({{ request_param }}Handle);
}
}