Port CustomMarshalers.dll to C# and .NET Core (#21343)
[platform/upstream/coreclr.git] / src / System.Private.CoreLib / src / System / Runtime / InteropServices / CustomMarshalers / EnumeratorToEnumVariantMarshaler.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 using System;
6 using System.Collections;
7 using System.Collections.Generic;
8 using System.Runtime.InteropServices.ComTypes;
9 using System.Text;
10
11 namespace System.Runtime.InteropServices.CustomMarshalers
12 {
13     internal class EnumeratorToEnumVariantMarshaler : ICustomMarshaler
14     {
15         private static readonly EnumeratorToEnumVariantMarshaler s_enumeratorToEnumVariantMarshaler = new EnumeratorToEnumVariantMarshaler();
16
17         public static ICustomMarshaler GetInstance(string cookie) => s_enumeratorToEnumVariantMarshaler;
18
19         private EnumeratorToEnumVariantMarshaler()
20         {
21         }
22
23         public void CleanUpManagedData(object ManagedObj)
24         {
25         }
26
27         public void CleanUpNativeData(IntPtr pNativeData)
28         {
29             Marshal.Release(pNativeData);
30         }
31
32         public int GetNativeDataSize()
33         {
34             // Return -1 to indicate the managed type this marshaler handles is not a value type.
35             return -1;
36         }
37
38         public IntPtr MarshalManagedToNative(object ManagedObj)
39         {
40             if (ManagedObj == null)
41             {
42                 throw new ArgumentNullException(nameof(ManagedObj));
43             }
44
45             if (ManagedObj is EnumeratorViewOfEnumVariant view)
46             {
47                 return Marshal.GetComInterfaceForObject<object, IEnumVARIANT>(view.GetUnderlyingObject());
48             }
49
50             EnumVariantViewOfEnumerator nativeView = new EnumVariantViewOfEnumerator((IEnumerator)ManagedObj);
51
52             return Marshal.GetComInterfaceForObject<EnumVariantViewOfEnumerator, IEnumVARIANT>(nativeView);
53         }
54
55         public object MarshalNativeToManaged(IntPtr pNativeData)
56         {
57             if (pNativeData == IntPtr.Zero)
58             {
59                 throw new ArgumentNullException(nameof(pNativeData));
60             }
61
62             object comObject = Marshal.GetObjectForIUnknown(pNativeData);
63
64             if (!comObject.GetType().IsCOMObject)
65             {
66                 if (comObject is EnumVariantViewOfEnumerator enumVariantView)
67                 {
68                     return enumVariantView.Enumerator;
69                 }
70
71                 return comObject as IEnumerator;
72             }
73
74             return ComDataHelpers.GetOrCreateManagedViewFromComData<IEnumVARIANT, EnumeratorViewOfEnumVariant>(comObject, var => new EnumeratorViewOfEnumVariant(var));
75         }
76     }
77 }