Skip to content
Snippets Groups Projects
Commit 60324922 authored by Jan Tattermusch's avatar Jan Tattermusch
Browse files

allow utf8 encoded status message

parent 2e5e5f66
No related branches found
No related tags found
No related merge requests found
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
using Grpc.Core; using Grpc.Core;
namespace Grpc.Core.Internal namespace Grpc.Core.Internal
...@@ -42,6 +43,7 @@ namespace Grpc.Core.Internal ...@@ -42,6 +43,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
{ {
static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8;
static readonly NativeMethods Native = NativeMethods.Get(); static readonly NativeMethods Native = NativeMethods.Get();
private BatchContextSafeHandle() private BatchContextSafeHandle()
...@@ -73,7 +75,7 @@ namespace Grpc.Core.Internal ...@@ -73,7 +75,7 @@ namespace Grpc.Core.Internal
{ {
UIntPtr detailsLength; UIntPtr detailsLength;
IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength); IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength);
string details = Marshal.PtrToStringAnsi(detailsPtr, (int) detailsLength.ToUInt32()); string details = PtrToStringUtf8(detailsPtr, (int) detailsLength.ToUInt32());
var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details); var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);
IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this); IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
...@@ -106,5 +108,12 @@ namespace Grpc.Core.Internal ...@@ -106,5 +108,12 @@ namespace Grpc.Core.Internal
Native.grpcsharp_batch_context_destroy(handle); Native.grpcsharp_batch_context_destroy(handle);
return true; return true;
} }
string PtrToStringUtf8(IntPtr ptr, int len)
{
var bytes = new byte[len];
Marshal.Copy(ptr, bytes, 0, len);
return EncodingUTF8.GetString(bytes);
}
} }
} }
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
using Grpc.Core; using Grpc.Core;
using Grpc.Core.Utils; using Grpc.Core.Utils;
using Grpc.Core.Profiling; using Grpc.Core.Profiling;
...@@ -44,6 +45,7 @@ namespace Grpc.Core.Internal ...@@ -44,6 +45,7 @@ namespace Grpc.Core.Internal
internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall
{ {
public static readonly CallSafeHandle NullInstance = new CallSafeHandle(); public static readonly CallSafeHandle NullInstance = new CallSafeHandle();
static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8;
static readonly NativeMethods Native = NativeMethods.Get(); static readonly NativeMethods Native = NativeMethods.Get();
const uint GRPC_WRITE_BUFFER_HINT = 1; const uint GRPC_WRITE_BUFFER_HINT = 1;
...@@ -138,7 +140,8 @@ namespace Grpc.Core.Internal ...@@ -138,7 +140,8 @@ namespace Grpc.Core.Internal
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero; var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata, var statusDetailBytes = EncodingUTF8.GetBytes(status.Detail);
Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata,
optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
} }
} }
......
...@@ -336,7 +336,7 @@ namespace Grpc.Core.Internal ...@@ -336,7 +336,7 @@ namespace Grpc.Core.Internal
public delegate CallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call, public delegate CallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx); BatchContextSafeHandle ctx);
public delegate CallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call, public delegate CallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags);
public delegate CallError grpcsharp_call_recv_message_delegate(CallSafeHandle call, public delegate CallError grpcsharp_call_recv_message_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx); BatchContextSafeHandle ctx);
......
...@@ -734,14 +734,15 @@ grpcsharp_call_send_close_from_client(grpc_call *call, ...@@ -734,14 +734,15 @@ grpcsharp_call_send_close_from_client(grpc_call *call,
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server( GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
grpc_call *call, grpcsharp_batch_context *ctx, grpc_status_code status_code, grpc_call *call, grpcsharp_batch_context *ctx, grpc_status_code status_code,
const char *status_details, grpc_metadata_array *trailing_metadata, const char *status_details, size_t status_details_len,
grpc_metadata_array *trailing_metadata,
int32_t send_empty_initial_metadata, const char* optional_send_buffer, int32_t send_empty_initial_metadata, const char* optional_send_buffer,
size_t optional_send_buffer_len, uint32_t write_flags) { size_t optional_send_buffer_len, uint32_t write_flags) {
/* TODO: don't use magic number */ /* TODO: don't use magic number */
grpc_op ops[3]; grpc_op ops[3];
memset(ops, 0, sizeof(ops)); memset(ops, 0, sizeof(ops));
size_t nops = 1; size_t nops = 1;
grpc_slice status_details_slice = grpc_slice_from_copied_string(status_details); grpc_slice status_details_slice = grpc_slice_from_copied_buffer(status_details, status_details_len);
ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER; ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
ops[0].data.send_status_from_server.status = status_code; ops[0].data.send_status_from_server.status = status_code;
ops[0].data.send_status_from_server.status_details = &status_details_slice; ops[0].data.send_status_from_server.status_details = &status_details_slice;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment