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; } } }