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.
6 using System.Diagnostics;
7 using Internal.Runtime.CompilerServices;
9 namespace System.Runtime.InteropServices.WindowsRuntime
11 // This is a set of stub methods implementing the support for the IList interface on WinRT
12 // objects that support IBindableVector. Used by the interop mashaling infrastructure.
14 // The methods on this class must be written VERY carefully to avoid introducing security holes.
15 // That's because they are invoked with special "this"! The "this" object
16 // for all of these methods are not BindableVectorToListAdapter objects. Rather, they are
17 // of type IBindableVector. No actual BindableVectorToListAdapter object is ever instantiated.
18 // Thus, you will see a lot of expressions that cast "this" to "IBindableVector".
19 internal sealed class BindableVectorToListAdapter
21 private BindableVectorToListAdapter()
23 Debug.Fail("This class is never instantiated");
26 // object this[int index] { get }
27 internal object? Indexer_Get(int index)
30 throw new ArgumentOutOfRangeException(nameof(index));
32 IBindableVector _this = Unsafe.As<IBindableVector>(this);
33 return GetAt(_this, (uint)index);
36 // object this[int index] { set }
37 internal void Indexer_Set(int index, object value)
40 throw new ArgumentOutOfRangeException(nameof(index));
42 IBindableVector _this = Unsafe.As<IBindableVector>(this);
43 SetAt(_this, (uint)index, value);
46 // int Add(object value)
47 internal int Add(object value)
49 IBindableVector _this = Unsafe.As<IBindableVector>(this);
52 uint size = _this.Size;
53 if (((uint)int.MaxValue) < size)
55 throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
58 return (int)(size - 1);
61 // bool Contains(object item)
62 internal bool Contains(object item)
64 IBindableVector _this = Unsafe.As<IBindableVector>(this);
67 return _this.IndexOf(item, out index);
73 IBindableVector _this = Unsafe.As<IBindableVector>(this);
77 // bool IsFixedSize { get }
78 internal bool IsFixedSize()
83 // bool IsReadOnly { get }
84 internal bool IsReadOnly()
89 // int IndexOf(object item)
90 internal int IndexOf(object item)
92 IBindableVector _this = Unsafe.As<IBindableVector>(this);
95 bool exists = _this.IndexOf(item, out index);
100 if (((uint)int.MaxValue) < index)
102 throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
108 // void Insert(int index, object item)
109 internal void Insert(int index, object item)
112 throw new ArgumentOutOfRangeException(nameof(index));
114 IBindableVector _this = Unsafe.As<IBindableVector>(this);
115 InsertAtHelper(_this, (uint)index, item);
118 // bool Remove(object item)
119 internal void Remove(object item)
121 IBindableVector _this = Unsafe.As<IBindableVector>(this);
124 bool exists = _this.IndexOf(item, out index);
128 if (((uint)int.MaxValue) < index)
130 throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
133 RemoveAtHelper(_this, index);
137 // void RemoveAt(int index)
138 internal void RemoveAt(int index)
141 throw new ArgumentOutOfRangeException(nameof(index));
143 IBindableVector _this = Unsafe.As<IBindableVector>(this);
144 RemoveAtHelper(_this, (uint)index);
149 private static object? GetAt(IBindableVector _this, uint index)
153 return _this.GetAt(index);
155 // We delegate bounds checking to the underlying collection and if it detected a fault,
156 // we translate it to the right exception:
160 if (HResults.E_BOUNDS == ex.HResult)
161 throw new ArgumentOutOfRangeException(nameof(index));
167 private static void SetAt(IBindableVector _this, uint index, object value)
171 _this.SetAt(index, value);
173 // We delegate bounds checking to the underlying collection and if it detected a fault,
174 // we translate it to the right exception:
178 if (HResults.E_BOUNDS == ex.HResult)
179 throw new ArgumentOutOfRangeException(nameof(index));
185 private static void InsertAtHelper(IBindableVector _this, uint index, object item)
189 _this.InsertAt(index, item);
191 // We delegate bounds checking to the underlying collection and if it detected a fault,
192 // we translate it to the right exception:
196 if (HResults.E_BOUNDS == ex.HResult)
197 throw new ArgumentOutOfRangeException(nameof(index));
203 private static void RemoveAtHelper(IBindableVector _this, uint index)
207 _this.RemoveAt(index);
209 // We delegate bounds checking to the underlying collection and if it detected a fault,
210 // we translate it to the right exception:
214 if (HResults.E_BOUNDS == ex.HResult)
215 throw new ArgumentOutOfRangeException(nameof(index));