blob: 427c16fac60bc4066d611bb08efb254d3acd8c98 [file] [log] [blame]
Jan Tattermuschc0b37212015-03-13 08:35:41 -07001#region Copyright notice and license
2// Copyright 2015, Google Inc.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30#endregion
31using System;
32using System.Runtime.InteropServices;
33using System.Threading.Tasks;
34
35namespace Grpc.Core.Internal
36{
37 /// <summary>
38 /// grpc_metadata_array from <grpc/grpc.h>
39 /// </summary>
40 internal class MetadataArraySafeHandle : SafeHandleZeroIsInvalid
41 {
42 [DllImport("grpc_csharp_ext.dll")]
43 static extern MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity);
44
45 [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
46 static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
47
48 [DllImport("grpc_csharp_ext.dll")]
Jan Tattermuschec50f282015-07-20 19:44:29 -070049 static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray);
50
51 [DllImport("grpc_csharp_ext.dll")]
Jan Tattermusch77172022015-07-21 18:28:16 -070052 static extern IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index);
53
54 [DllImport("grpc_csharp_ext.dll")]
55 static extern IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index);
56
57 [DllImport("grpc_csharp_ext.dll")]
58 static extern UIntPtr grpcsharp_metadata_array_get_value_length(IntPtr metadataArray, UIntPtr index);
Jan Tattermuschec50f282015-07-20 19:44:29 -070059
60 [DllImport("grpc_csharp_ext.dll")]
Jan Tattermuschc0b37212015-03-13 08:35:41 -070061 static extern void grpcsharp_metadata_array_destroy_full(IntPtr array);
62
63 private MetadataArraySafeHandle()
64 {
65 }
Jan Tattermuschec50f282015-07-20 19:44:29 -070066
Jan Tattermuschc0b37212015-03-13 08:35:41 -070067 public static MetadataArraySafeHandle Create(Metadata metadata)
68 {
Jan Tattermusche5c9b802015-07-14 17:46:58 -070069 // TODO(jtattermusch): we might wanna check that the metadata is readonly
70 var metadataArray = grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
71 for (int i = 0; i < metadata.Count; i++)
Jan Tattermuschc0b37212015-03-13 08:35:41 -070072 {
Jan Tattermusche5c9b802015-07-14 17:46:58 -070073 grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, metadata[i].ValueBytes, new UIntPtr((ulong)metadata[i].ValueBytes.Length));
Jan Tattermuschc0b37212015-03-13 08:35:41 -070074 }
75 return metadataArray;
76 }
77
Jan Tattermuschec50f282015-07-20 19:44:29 -070078 /// <summary>
79 /// Reads metadata from pointer to grpc_metadata_array
80 /// </summary>
81 public static Metadata ReadMetadataFromPtrUnsafe(IntPtr metadataArray)
82 {
83 if (metadataArray == IntPtr.Zero)
84 {
85 return null;
86 }
87
88 ulong count = grpcsharp_metadata_array_count(metadataArray).ToUInt64();
89
90 var metadata = new Metadata();
Jan Tattermuschae017092015-07-22 11:59:13 -070091 for (ulong i = 0; i < count; i++)
Jan Tattermuschec50f282015-07-20 19:44:29 -070092 {
Jan Tattermusch77172022015-07-21 18:28:16 -070093 var index = new UIntPtr(i);
94 string key = Marshal.PtrToStringAnsi(grpcsharp_metadata_array_get_key(metadataArray, index));
95 var bytes = new byte[grpcsharp_metadata_array_get_value_length(metadataArray, index).ToUInt64()];
96 Marshal.Copy(grpcsharp_metadata_array_get_value(metadataArray, index), bytes, 0, bytes.Length);
Jan Tattermuschec50f282015-07-20 19:44:29 -070097 metadata.Add(new Metadata.Entry(key, bytes));
98 }
99 return metadata;
100 }
101
102 internal IntPtr Handle
103 {
104 get
105 {
106 return handle;
107 }
108 }
109
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700110 protected override bool ReleaseHandle()
111 {
112 grpcsharp_metadata_array_destroy_full(handle);
113 return true;
114 }
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700115 }
116}