Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / mscorlib / system / runtime / interopservices / windowsruntime / dictionarytomapadapter.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.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;
19
20 namespace System.Runtime.InteropServices.WindowsRuntime
21 {
22     // This is a set of stub methods implementing the support for the IMap`2 interface on managed
23     // objects that implement IDictionary`2. 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 DictionaryToMapAdapter objects. Rather, they are of type
28     // IDictionary<K, V>. No actual DictionaryToMapAdapter object is ever instantiated. Thus, you will
29     // see a lot of expressions that cast "this" to "IDictionary<K, V>". 
30     internal sealed class DictionaryToMapAdapter
31     {
32         private DictionaryToMapAdapter()
33         {
34             Contract.Assert(false, "This class is never instantiated");
35         }
36
37         // V Lookup(K key)
38         [SecurityCritical]
39         internal V Lookup<K, V>(K key)
40         {
41             IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
42             V value;
43             bool keyFound = _this.TryGetValue(key, out value);
44
45             if (!keyFound)
46             {
47                 Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
48                 e.SetErrorCode(__HResults.E_BOUNDS);
49                 throw e;
50             }
51
52             return value;
53         }
54
55         // uint Size { get }
56         [SecurityCritical]
57         internal uint Size<K, V>()
58         {
59             IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
60             return (uint)_this.Count;
61         }
62         
63         // bool HasKey(K key)
64         [SecurityCritical]
65         internal bool HasKey<K, V>(K key)
66         {
67             IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
68             return _this.ContainsKey(key);
69         }
70
71         // IMapView<K, V> GetView()
72         [SecurityCritical]
73         internal IReadOnlyDictionary<K, V> GetView<K, V>()
74         {
75             IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
76             Contract.Assert(_this != null);
77
78             // Note: This dictionary is not really read-only - you could QI for a modifiable
79             // dictionary.  We gain some perf by doing this.  We believe this is acceptable.
80             IReadOnlyDictionary<K, V> roDictionary = _this as IReadOnlyDictionary<K, V>;
81             if (roDictionary == null)
82             {
83                 roDictionary = new ReadOnlyDictionary<K, V>(_this);
84             }
85             return roDictionary;
86         }
87
88         // bool Insert(K key, V value)
89         [SecurityCritical]
90         internal bool Insert<K, V>(K key, V value)
91         {
92             IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
93             bool replacing = _this.ContainsKey(key);
94             _this[key] = value;
95             return replacing;
96         }
97
98         // void Remove(K key)
99         [SecurityCritical]
100         internal void Remove<K, V>(K key)
101         {
102             IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
103             bool removed = _this.Remove(key);
104
105             if (!removed)
106             {
107                 Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
108                 e.SetErrorCode(__HResults.E_BOUNDS);
109                 throw e;
110             }
111         }
112
113         // void Clear()
114         [SecurityCritical]
115         internal void Clear<K, V>()
116         {
117             IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
118             _this.Clear();
119         }
120     }
121 }