• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Copyright 2015 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 #endregion
16 using System;
17 using System.Runtime.InteropServices;
18 using System.Threading.Tasks;
19 using Grpc.Core.Profiling;
20 
21 namespace Grpc.Core.Internal
22 {
23     /// <summary>
24     /// grpc_metadata_array from <c>grpc/grpc.h</c>
25     /// </summary>
26     internal class MetadataArraySafeHandle : SafeHandleZeroIsInvalid
27     {
28         static readonly NativeMethods Native = NativeMethods.Get();
29 
MetadataArraySafeHandle()30         private MetadataArraySafeHandle()
31         {
32         }
33 
Create(Metadata metadata)34         public static MetadataArraySafeHandle Create(Metadata metadata)
35         {
36             if (metadata.Count == 0)
37             {
38                 return new MetadataArraySafeHandle();
39             }
40 
41             // TODO(jtattermusch): we might wanna check that the metadata is readonly
42             var metadataArray = Native.grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
43             for (int i = 0; i < metadata.Count; i++)
44             {
45                 var valueBytes = metadata[i].GetSerializedValueUnsafe();
46                 Native.grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length));
47             }
48             return metadataArray;
49         }
50 
51         /// <summary>
52         /// Reads metadata from pointer to grpc_metadata_array
53         /// </summary>
ReadMetadataFromPtrUnsafe(IntPtr metadataArray)54         public static Metadata ReadMetadataFromPtrUnsafe(IntPtr metadataArray)
55         {
56             if (metadataArray == IntPtr.Zero)
57             {
58                 return null;
59             }
60 
61             ulong count = Native.grpcsharp_metadata_array_count(metadataArray).ToUInt64();
62 
63             var metadata = new Metadata();
64             for (ulong i = 0; i < count; i++)
65             {
66                 var index = new UIntPtr(i);
67                 UIntPtr keyLen;
68                 IntPtr keyPtr = Native.grpcsharp_metadata_array_get_key(metadataArray, index, out keyLen);
69                 string key = Marshal.PtrToStringAnsi(keyPtr, (int)keyLen.ToUInt32());
70                 UIntPtr valueLen;
71                 IntPtr valuePtr = Native.grpcsharp_metadata_array_get_value(metadataArray, index, out valueLen);
72                 var bytes = new byte[valueLen.ToUInt64()];
73                 Marshal.Copy(valuePtr, bytes, 0, bytes.Length);
74                 metadata.Add(Metadata.Entry.CreateUnsafe(key, bytes));
75             }
76             return metadata;
77         }
78 
79         internal IntPtr Handle
80         {
81             get
82             {
83                 return handle;
84             }
85         }
86 
ReleaseHandle()87         protected override bool ReleaseHandle()
88         {
89             Native.grpcsharp_metadata_array_destroy_full(handle);
90             return true;
91         }
92     }
93 }
94