reading of metadata
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index 861cbbe..bfd88a0 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -47,6 +47,9 @@
static extern BatchContextSafeHandle grpcsharp_batch_context_create();
[DllImport("grpc_csharp_ext.dll")]
+ static extern IntPtr grpcsharp_batch_context_receive_initial_metadata(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
@@ -59,12 +62,18 @@
static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
+ static extern IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
+ static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
static extern int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
@@ -87,13 +96,24 @@
}
}
+ public Metadata GetReceivedInitialMetadata()
+ {
+ IntPtr metadataArrayPtr = grpcsharp_batch_context_receive_initial_metadata(this);
+ return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
+ }
+
public Status GetReceivedStatus()
{
- // TODO: can the native method return string directly?
string details = Marshal.PtrToStringAnsi(grpcsharp_batch_context_recv_status_on_client_details(this));
return new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details);
}
+ public Metadata GetReceivedStatusTrailingMetadata()
+ {
+ IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
+ return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
+ }
+
public byte[] GetReceivedMessage()
{
IntPtr len = grpcsharp_batch_context_recv_message_length(this);
@@ -116,6 +136,12 @@
return Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this));
}
+ public Metadata GetServerRpcNewRequestMetadata()
+ {
+ IntPtr metadataArrayPtr = grpcsharp_batch_context_server_rpc_new_request_metadata(this);
+ return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
+ }
+
public bool GetReceivedCloseOnServerCancelled()
{
return grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
index 80aa7f5..e17eb89 100644
--- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
@@ -34,6 +34,8 @@
namespace Grpc.Core.Internal
{
+
+
/// <summary>
/// grpc_metadata_array from <grpc/grpc.h>
/// </summary>
@@ -46,12 +48,18 @@
static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
[DllImport("grpc_csharp_ext.dll")]
+ static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern MetadataEntryStruct grpcsharp_metadata_array_get(IntPtr metadataArray, UIntPtr index);
+
+ [DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_metadata_array_destroy_full(IntPtr array);
private MetadataArraySafeHandle()
{
}
-
+
public static MetadataArraySafeHandle Create(Metadata metadata)
{
// TODO(jtattermusch): we might wanna check that the metadata is readonly
@@ -63,10 +71,53 @@
return metadataArray;
}
+ /// <summary>
+ /// Reads metadata from pointer to grpc_metadata_array
+ /// </summary>
+ public static Metadata ReadMetadataFromPtrUnsafe(IntPtr metadataArray)
+ {
+ if (metadataArray == IntPtr.Zero)
+ {
+ return null;
+ }
+
+ ulong count = grpcsharp_metadata_array_count(metadataArray).ToUInt64();
+
+ var metadata = new Metadata();
+ for (ulong index = 0; index < count; index ++)
+ {
+ var rawEntry = grpcsharp_metadata_array_get(metadataArray, new UIntPtr(index));
+ string key = Marshal.PtrToStringAnsi(rawEntry.key);
+ var bytes = new byte[rawEntry.valueLength.ToUInt64()];
+ Marshal.Copy(rawEntry.value, bytes, 0, bytes.Length);
+ metadata.Add(new Metadata.Entry(key, bytes));
+ }
+ return metadata;
+ }
+
+ internal IntPtr Handle
+ {
+ get
+ {
+ return handle;
+ }
+ }
+
protected override bool ReleaseHandle()
{
grpcsharp_metadata_array_destroy_full(handle);
return true;
}
+
+ /// <summary>
+ /// gprc_metadata from grpc/grpc.h
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ private struct MetadataEntryStruct
+ {
+ public IntPtr key; // const char*
+ public IntPtr value; // const char*
+ public UIntPtr valueLength;
+ }
}
}
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 7dd1959..d8996ae 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -167,6 +167,17 @@
array->count++;
}
+GPR_EXPORT gpr_intptr GPR_CALLTYPE
+grpcsharp_metadata_array_count(grpc_metadata_array *array) {
+ return (gpr_intptr) array->count;
+}
+
+GPR_EXPORT const grpc_metadata *GPR_CALLTYPE
+grpcsharp_metadata_array_get(grpc_metadata_array *array, size_t index) {
+ GPR_ASSERT(index < array->count);
+ return array->metadata[index];
+}
+
/* Move contents of metadata array */
void grpcsharp_metadata_array_move(grpc_metadata_array *dest,
grpc_metadata_array *src) {
@@ -218,6 +229,12 @@
gpr_free(ctx);
}
+GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
+grpcsharp_batch_context_receive_initial_metadata(
+ const grpcsharp_batch_context *ctx) {
+ return &(ctx->recv_initial_metadata);
+}
+
GPR_EXPORT gpr_intptr GPR_CALLTYPE grpcsharp_batch_context_recv_message_length(
const grpcsharp_batch_context *ctx) {
if (!ctx->recv_message) {
@@ -260,6 +277,12 @@
return ctx->recv_status_on_client.status_details;
}
+GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
+grpcsharp_batch_context_recv_status_on_client_trailing_metadata(
+ const grpcsharp_batch_context *ctx) {
+ return &(ctx->recv_status_on_client.trailing_metadata);
+}
+
GPR_EXPORT grpc_call *GPR_CALLTYPE grpcsharp_batch_context_server_rpc_new_call(
const grpcsharp_batch_context *ctx) {
return ctx->server_rpc_new.call;
@@ -271,6 +294,12 @@
return ctx->server_rpc_new.call_details.method;
}
+GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
+grpcsharp_batch_context_server_rpc_new_request_metadata(
+ const grpcsharp_batch_context *ctx) {
+ return &(ctx->server_rpc_new.request_metadata);
+}
+
GPR_EXPORT gpr_int32 GPR_CALLTYPE
grpcsharp_batch_context_recv_close_on_server_cancelled(
const grpcsharp_batch_context *ctx) {