Nullable: System.Runtime.InteropServices.CustomMarshalers/WindowsRuntime (#23930)
[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 #nullable enable
6 using System.Collections;
7 using System.Runtime.InteropServices.ComTypes;
8
9 namespace System.Runtime.InteropServices.CustomMarshalers
10 {
11     internal class EnumeratorToEnumVariantMarshaler : ICustomMarshaler
12     {
13         private static readonly EnumeratorToEnumVariantMarshaler s_enumeratorToEnumVariantMarshaler = new EnumeratorToEnumVariantMarshaler();
14
15         public static ICustomMarshaler GetInstance(string? cookie) => s_enumeratorToEnumVariantMarshaler;
16
17         private EnumeratorToEnumVariantMarshaler()
18         {
19         }
20
21         public void CleanUpManagedData(object ManagedObj)
22         {
23         }
24
25         public void CleanUpNativeData(IntPtr pNativeData)
26         {
27             Marshal.Release(pNativeData);
28         }
29
30         public int GetNativeDataSize()
31         {
32             // Return -1 to indicate the managed type this marshaler handles is not a value type.
33             return -1;
34         }
35
36         public IntPtr MarshalManagedToNative(object ManagedObj)
37         {
38             if (ManagedObj == null)
39             {
40                 throw new ArgumentNullException(nameof(ManagedObj));
41             }
42
43             if (ManagedObj is EnumeratorViewOfEnumVariant view)
44             {
45                 return Marshal.GetComInterfaceForObject<object, IEnumVARIANT>(view.GetUnderlyingObject());
46             }
47
48             EnumVariantViewOfEnumerator nativeView = new EnumVariantViewOfEnumerator((IEnumerator)ManagedObj);
49
50             return Marshal.GetComInterfaceForObject<EnumVariantViewOfEnumerator, IEnumVARIANT>(nativeView);
51         }
52
53         public object MarshalNativeToManaged(IntPtr pNativeData)
54         {
55             if (pNativeData == IntPtr.Zero)
56             {
57                 throw new ArgumentNullException(nameof(pNativeData));
58             }
59
60             object comObject = Marshal.GetObjectForIUnknown(pNativeData);
61
62             if (!comObject.GetType().IsCOMObject)
63             {
64                 if (comObject is EnumVariantViewOfEnumerator enumVariantView)
65                 {
66                     return enumVariantView.Enumerator;
67                 }
68
69                 return (comObject as IEnumerator)!;
70             }
71
72             return ComDataHelpers.GetOrCreateManagedViewFromComData<IEnumVARIANT, EnumeratorViewOfEnumVariant>(comObject, var => new EnumeratorViewOfEnumVariant(var));
73         }
74     }
75 }