Nullable: System.Runtime.InteropServices.CustomMarshalers/WindowsRuntime (#23930)
[platform/upstream/coreclr.git] / src / System.Private.CoreLib / src / System / Runtime / InteropServices / CustomMarshalers / EnumVariantViewOfEnumerator.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 EnumVariantViewOfEnumerator : IEnumVARIANT, ICustomAdapter
12     {
13         public EnumVariantViewOfEnumerator(IEnumerator enumerator)
14         {
15             if (enumerator is null)
16             {
17                 throw new ArgumentNullException(nameof(enumerator));
18             }
19
20             Enumerator = enumerator;
21         }
22
23         public IEnumerator Enumerator { get; }
24
25         public IEnumVARIANT Clone()
26         {
27             if (Enumerator is ICloneable clonable)
28             {
29                 return new EnumVariantViewOfEnumerator((IEnumerator)clonable.Clone());
30             }
31             else
32             {
33                 throw new COMException(SR.Arg_EnumNotCloneable, HResults.E_FAIL);
34             }
35         }
36
37         public int Next(int celt, object?[] rgVar, IntPtr pceltFetched)
38         {
39             int numElements = 0;
40
41             try
42             {
43                 if (celt > 0 && rgVar == null)
44                 {
45                     return HResults.E_INVALIDARG;
46                 }
47
48                 while ((numElements < celt) && Enumerator.MoveNext())
49                 {
50                     rgVar[numElements++] = Enumerator.Current;
51                 }
52
53                 if (pceltFetched != IntPtr.Zero)
54                 {
55                     Marshal.WriteInt32(pceltFetched, numElements);
56                 }
57             }
58             catch (Exception e)
59             {
60                 return e.HResult;
61             }
62
63             return numElements == celt ? HResults.S_OK : HResults.S_FALSE;
64         }
65
66         public int Reset()
67         {
68             try
69             {
70                 Enumerator.Reset();
71             }
72             catch (Exception e)
73             {
74                 return e.HResult;
75             }
76
77             return HResults.S_OK;
78         }
79
80         public int Skip(int celt)
81         {
82             try
83             {
84                 while (celt > 0 && Enumerator.MoveNext())
85                 {
86                     celt--;
87                 }
88             }
89             catch (Exception e)
90             {
91                 return e.HResult;
92             }
93
94             return celt == 0 ? HResults.S_OK : HResults.S_FALSE;
95         }
96
97         public object GetUnderlyingObject()
98         {
99             return Enumerator;
100         }
101     }
102 }