Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / mscorlib / system / runtime / interopservices / windowsruntime / mapviewtoreadonlycollectionadapter.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 //
7 // <OWNER>GPaperin</OWNER>
8 // <OWNER>Microsoft</OWNER>
9
10 using System;
11 using System.Security;
12 using System.Collections;
13 using System.Collections.Generic;
14 using System.Diagnostics.Contracts;
15 using System.Runtime.InteropServices;
16 using System.Runtime.CompilerServices;
17
18 namespace System.Runtime.InteropServices.WindowsRuntime
19 {
20     // These stubs will be used when a call via IReadOnlyCollection<KeyValuePair<K, V>> is made in managed code.
21     // This can mean two things - either the underlying unmanaged object implements IMapView<K, V> or it
22     // implements IVectorView<IKeyValuePair<K, V>> and we cannot determine this statically in the general
23     // case so we have to cast at run-time. Used by the interop mashaling infrastructure.
24     //
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 MapViewToReadOnlyCollectionAdapter objects. Rather, they are of type
28     // IVectorView<KeyValuePair<K, V>> or IMapView<K, V>. No actual MapViewToReadOnlyCollectionAdapter object is ever
29     // instantiated. Thus, you will see a lot of expressions that cast "this" to "IVectorView<KeyValuePair<K, V>>"
30     // or "IMapView<K, V>".
31     internal sealed class MapViewToReadOnlyCollectionAdapter
32     {
33         private MapViewToReadOnlyCollectionAdapter()
34         {
35             Contract.Assert(false, "This class is never instantiated");
36         }
37
38         // int Count { get }
39         [Pure]
40         [SecurityCritical]
41         internal int Count<K, V>()
42         {
43             object _this = JitHelpers.UnsafeCast<object>(this);
44
45             IMapView<K, V> _this_map = _this as IMapView<K, V>;
46             if (_this_map != null)
47             {
48                 uint size = _this_map.Size;
49
50                 if (((uint)Int32.MaxValue) < size)
51                 {
52                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingDictionaryTooLarge"));
53                 }
54
55                 return (int)size;
56             }
57             else
58             {
59                 IVectorView<KeyValuePair<K, V>> _this_vector = JitHelpers.UnsafeCast<IVectorView<KeyValuePair<K, V>>>(this);
60                 uint size = _this_vector.Size;
61
62                 if (((uint)Int32.MaxValue) < size)
63                 {
64                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
65                 }
66
67                 return (int)size;
68             }
69         }
70     }
71 }