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 ICollection 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 BindableVectorToCollectionAdapter objects. Rather, they are
17 // of type IBindableVector. No actual BindableVectorToCollectionAdapter object is ever instantiated.
18 // Thus, you will see a lot of expressions that cast "this" to "IBindableVector".
19 internal sealed class BindableVectorToCollectionAdapter
21 private BindableVectorToCollectionAdapter()
23 Debug.Fail("This class is never instantiated");
29 IBindableVector _this = Unsafe.As<IBindableVector>(this);
30 uint size = _this.Size;
31 if (((uint)int.MaxValue) < size)
33 throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
39 // bool IsSynchronized { get }
40 internal bool IsSynchronized()
45 // object SyncRoot { get }
46 internal object SyncRoot()
51 // void CopyTo(Array array, int index)
52 internal void CopyTo(Array array, int arrayIndex)
55 throw new ArgumentNullException(nameof(array));
57 // ICollection expects the destination array to be single-dimensional.
59 throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
61 int destLB = array.GetLowerBound(0);
64 int destLen = array.GetLength(0);
66 if (arrayIndex < destLB)
67 throw new ArgumentOutOfRangeException(nameof(arrayIndex));
69 // Does the dimension in question have sufficient space to copy the expected number of entries?
70 // We perform this check before valid index check to ensure the exception message is in sync with
71 // the following snippet that uses regular framework code:
73 // ArrayList list = new ArrayList();
75 // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 });
76 // list.CopyTo(items, 0);
78 if (srcLen > (destLen - (arrayIndex - destLB)))
79 throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
81 if (arrayIndex - destLB > destLen)
82 throw new ArgumentException(SR.Argument_IndexOutOfArrayBounds);
84 // We need to verify the index as we;
85 IBindableVector _this = Unsafe.As<IBindableVector>(this);
87 for (uint i = 0; i < srcLen; i++)
89 array.SetValue(_this.GetAt(i), i + arrayIndex);