Nullable: System.Runtime.InteropServices.CustomMarshalers/WindowsRuntime (#23930)
[platform/upstream/coreclr.git] / src / System.Private.CoreLib / src / System / Runtime / InteropServices / WindowsRuntime / ListToBindableVectorViewAdapter.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
8 namespace System.Runtime.InteropServices.WindowsRuntime
9 {
10     /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing
11     /// it to Windows runtime interop.
12     internal sealed class ListToBindableVectorViewAdapter : IBindableVectorView
13     {
14         private readonly IList list;
15
16         internal ListToBindableVectorViewAdapter(IList list)
17         {
18             if (list == null)
19                 throw new ArgumentNullException(nameof(list));
20
21
22             this.list = list;
23         }
24
25         private static void EnsureIndexInt32(uint index, int listCapacity)
26         {
27             // We use '<=' and not '<' becasue int.MaxValue == index would imply
28             // that Size > int.MaxValue:
29             if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity)
30             {
31                 Exception e = new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexLargerThanMaxValue);
32                 e.HResult = HResults.E_BOUNDS;
33                 throw e;
34             }
35         }
36
37         // IBindableIterable implementation:
38
39         public IBindableIterator First()
40         {
41             IEnumerator enumerator = list.GetEnumerator();
42             return new EnumeratorToIteratorAdapter<object?>(new EnumerableToBindableIterableAdapter.NonGenericToGenericEnumerator(enumerator));
43         }
44
45         // IBindableVectorView implementation:
46
47         public object? GetAt(uint index)
48         {
49             EnsureIndexInt32(index, list.Count);
50
51             try
52             {
53                 return list[(int)index];
54             }
55             catch (ArgumentOutOfRangeException ex)
56             {
57                 throw WindowsRuntimeMarshal.GetExceptionForHR(HResults.E_BOUNDS, ex, "ArgumentOutOfRange_IndexOutOfRange");
58             }
59         }
60
61         public uint Size
62         {
63             get
64             {
65                 return (uint)list.Count;
66             }
67         }
68
69         public bool IndexOf(object value, out uint index)
70         {
71             int ind = list.IndexOf(value);
72
73             if (-1 == ind)
74             {
75                 index = 0;
76                 return false;
77             }
78
79             index = (uint)ind;
80             return true;
81         }
82     }
83 }