using System;
using System.Runtime.InteropServices;
using Google.GRPC.Core;
namespace Google.GRPC.Core.Internal
{
///
/// grpc_event from grpc/grpc.h
///
internal class EventSafeHandle : SafeHandleZeroIsInvalid
{
[DllImport("libgrpc.so")]
static extern void grpc_event_finish(IntPtr ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern GRPCCompletionType grpc_event_type(EventSafeHandle ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern CallSafeHandle grpc_event_call(EventSafeHandle ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern GRPCOpError grpc_event_write_accepted(EventSafeHandle ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern GRPCOpError grpc_event_finish_accepted(EventSafeHandle ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern StatusCode grpc_event_finished_status(EventSafeHandle ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern IntPtr grpc_event_finished_details(EventSafeHandle ev); // returns const char*
[DllImport("libgrpc_csharp_ext.so")]
static extern IntPtr grpc_event_read_length(EventSafeHandle ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern void grpc_event_read_copy_to_buffer(EventSafeHandle ev, byte[] buffer, UIntPtr bufferLen);
[DllImport("libgrpc_csharp_ext.so")]
static extern IntPtr grpc_event_server_rpc_new_method(EventSafeHandle ev); // returns const char*
public GRPCCompletionType GetCompletionType()
{
return grpc_event_type(this);
}
public GRPCOpError GetWriteAccepted()
{
return grpc_event_write_accepted(this);
}
public GRPCOpError GetFinishAccepted()
{
return grpc_event_finish_accepted(this);
}
public Status GetFinished()
{
// TODO: can the native method return string directly?
string details = Marshal.PtrToStringAnsi(grpc_event_finished_details(this));
return new Status(grpc_event_finished_status(this), details);
}
public byte[] GetReadData()
{
IntPtr len = grpc_event_read_length(this);
if (len == new IntPtr(-1))
{
return null;
}
byte[] data = new byte[(int) len];
grpc_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
return data;
}
public CallSafeHandle GetCall() {
return grpc_event_call(this);
}
public string GetServerRpcNewMethod() {
// TODO: can the native method return string directly?
return Marshal.PtrToStringAnsi(grpc_event_server_rpc_new_method(this));
}
//TODO: client_metadata_read event type
protected override bool ReleaseHandle()
{
grpc_event_finish(handle);
return true;
}
}
// TODO: this is basically c&p of EventSafeHandle. Unify!
///
/// Not owned version of
/// grpc_event from grpc/grpc.h
///
internal class EventSafeHandleNotOwned : SafeHandleZeroIsInvalid
{
[DllImport("libgrpc.so")]
static extern void grpc_event_finish(IntPtr ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern GRPCCompletionType grpc_event_type(EventSafeHandleNotOwned ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern CallSafeHandle grpc_event_call(EventSafeHandleNotOwned ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern GRPCOpError grpc_event_write_accepted(EventSafeHandleNotOwned ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern GRPCOpError grpc_event_finish_accepted(EventSafeHandleNotOwned ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern StatusCode grpc_event_finished_status(EventSafeHandleNotOwned ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern IntPtr grpc_event_finished_details(EventSafeHandleNotOwned ev); // returns const char*
[DllImport("libgrpc_csharp_ext.so")]
static extern IntPtr grpc_event_read_length(EventSafeHandleNotOwned ev);
[DllImport("libgrpc_csharp_ext.so")]
static extern void grpc_event_read_copy_to_buffer(EventSafeHandleNotOwned ev, byte[] buffer, UIntPtr bufferLen);
[DllImport("libgrpc_csharp_ext.so")]
static extern IntPtr grpc_event_server_rpc_new_method(EventSafeHandleNotOwned ev); // returns const char*
public EventSafeHandleNotOwned() : base(false)
{
}
public EventSafeHandleNotOwned(IntPtr handle) : base(false)
{
SetHandle(handle);
}
public GRPCCompletionType GetCompletionType()
{
return grpc_event_type(this);
}
public GRPCOpError GetWriteAccepted()
{
return grpc_event_write_accepted(this);
}
public GRPCOpError GetFinishAccepted()
{
return grpc_event_finish_accepted(this);
}
public Status GetFinished()
{
// TODO: can the native method return string directly?
string details = Marshal.PtrToStringAnsi(grpc_event_finished_details(this));
return new Status(grpc_event_finished_status(this), details);
}
public byte[] GetReadData()
{
IntPtr len = grpc_event_read_length(this);
if (len == new IntPtr(-1))
{
return null;
}
byte[] data = new byte[(int) len];
grpc_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
return data;
}
public CallSafeHandle GetCall() {
return grpc_event_call(this);
}
public string GetServerRpcNewMethod() {
// TODO: can the native method return string directly?
return Marshal.PtrToStringAnsi(grpc_event_server_rpc_new_method(this));
}
//TODO: client_metadata_read event type
protected override bool ReleaseHandle()
{
grpc_event_finish(handle);
return true;
}
}
}