3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // <OWNER>GPaperin</OWNER>
8 // <OWNER>Microsoft</OWNER>
11 using System.Security;
12 using System.Reflection;
13 using System.Collections;
14 using System.Collections.Generic;
15 using System.Collections.ObjectModel;
16 using System.Diagnostics.Contracts;
17 using System.Runtime.InteropServices;
18 using System.Runtime.CompilerServices;
20 namespace System.Runtime.InteropServices.WindowsRuntime
22 // This is a set of stub methods implementing the support for the IBindableVector interface on managed
23 // objects that implement IList. Used by the interop mashaling infrastructure.
25 // The methods on this class must be written VERY carefully to avoid introducing security holes.
26 // That's because they are invoked with special "this"! The "this" object
27 // for all of these methods are not ListToBindableVectorAdapter objects. Rather, they are of type
28 // IList. No actual ListToVectorBindableAdapter object is ever instantiated. Thus, you will
29 // see a lot of expressions that cast "this" to "IList".
30 internal sealed class ListToBindableVectorAdapter
32 private ListToBindableVectorAdapter()
34 Contract.Assert(false, "This class is never instantiated");
37 // object GetAt(uint index)
39 internal object GetAt(uint index)
41 IList _this = JitHelpers.UnsafeCast<IList>(this);
42 EnsureIndexInt32(index, _this.Count);
46 return _this[(Int32)index];
48 catch (ArgumentOutOfRangeException ex)
50 throw WindowsRuntimeMarshal.GetExceptionForHR(__HResults.E_BOUNDS, ex, "ArgumentOutOfRange_IndexOutOfRange");
58 IList _this = JitHelpers.UnsafeCast<IList>(this);
59 return (uint)_this.Count;
62 // IBindableVectorView GetView()
64 internal IBindableVectorView GetView()
66 IList _this = JitHelpers.UnsafeCast<IList>(this);
67 return new ListToBindableVectorViewAdapter(_this);
70 // bool IndexOf(object value, out uint index)
72 internal bool IndexOf(object value, out uint index)
74 IList _this = JitHelpers.UnsafeCast<IList>(this);
75 int ind = _this.IndexOf(value);
87 // void SetAt(uint index, object value)
89 internal void SetAt(uint index, object value)
91 IList _this = JitHelpers.UnsafeCast<IList>(this);
92 EnsureIndexInt32(index, _this.Count);
96 _this[(int)index] = value;
98 catch (ArgumentOutOfRangeException ex)
100 throw WindowsRuntimeMarshal.GetExceptionForHR(__HResults.E_BOUNDS, ex, "ArgumentOutOfRange_IndexOutOfRange");
104 // void InsertAt(uint index, object value)
106 internal void InsertAt(uint index, object value)
108 IList _this = JitHelpers.UnsafeCast<IList>(this);
110 // Inserting at an index one past the end of the list is equivalent to appending
111 // so we need to ensure that we're within (0, count + 1).
112 EnsureIndexInt32(index, _this.Count + 1);
116 _this.Insert((int)index, value);
118 catch (ArgumentOutOfRangeException ex)
120 // Change error code to match what WinRT expects
121 ex.SetErrorCode(__HResults.E_BOUNDS);
126 // void RemoveAt(uint index)
128 internal void RemoveAt(uint index)
130 IList _this = JitHelpers.UnsafeCast<IList>(this);
131 EnsureIndexInt32(index, _this.Count);
135 _this.RemoveAt((Int32)index);
137 catch (ArgumentOutOfRangeException ex)
139 // Change error code to match what WinRT expects
140 ex.SetErrorCode(__HResults.E_BOUNDS);
145 // void Append(object value)
147 internal void Append(object value)
149 IList _this = JitHelpers.UnsafeCast<IList>(this);
153 // void RemoveAtEnd()
155 internal void RemoveAtEnd()
157 IList _this = JitHelpers.UnsafeCast<IList>(this);
158 if (_this.Count == 0)
160 Exception e = new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRemoveLastFromEmptyCollection"));
161 e.SetErrorCode(__HResults.E_BOUNDS);
165 uint size = (uint)_this.Count;
171 internal void Clear()
173 IList _this = JitHelpers.UnsafeCast<IList>(this);
179 private static void EnsureIndexInt32(uint index, int listCapacity)
181 // We use '<=' and not '<' becasue Int32.MaxValue == index would imply
182 // that Size > Int32.MaxValue:
183 if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
185 Exception e = new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
186 e.SetErrorCode(__HResults.E_BOUNDS);