// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. // using System; using System.Security; using System.Reflection; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; namespace System.Runtime.InteropServices.WindowsRuntime { // This is a set of stub methods implementing the support for the IMap`2 interface on managed // objects that implement IDictionary`2. Used by the interop mashaling infrastructure. // // The methods on this class must be written VERY carefully to avoid introducing security holes. // That's because they are invoked with special "this"! The "this" object // for all of these methods are not DictionaryToMapAdapter objects. Rather, they are of type // IDictionary. No actual DictionaryToMapAdapter object is ever instantiated. Thus, you will // see a lot of expressions that cast "this" to "IDictionary". internal sealed class DictionaryToMapAdapter { private DictionaryToMapAdapter() { Debug.Assert(false, "This class is never instantiated"); } // V Lookup(K key) internal V Lookup(K key) { IDictionary _this = JitHelpers.UnsafeCast>(this); V value; bool keyFound = _this.TryGetValue(key, out value); if (!keyFound) { Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound")); e.SetErrorCode(__HResults.E_BOUNDS); throw e; } return value; } // uint Size { get } internal uint Size() { IDictionary _this = JitHelpers.UnsafeCast>(this); return (uint)_this.Count; } // bool HasKey(K key) internal bool HasKey(K key) { IDictionary _this = JitHelpers.UnsafeCast>(this); return _this.ContainsKey(key); } // IMapView GetView() internal IReadOnlyDictionary GetView() { IDictionary _this = JitHelpers.UnsafeCast>(this); Debug.Assert(_this != null); // Note: This dictionary is not really read-only - you could QI for a modifiable // dictionary. We gain some perf by doing this. We believe this is acceptable. IReadOnlyDictionary roDictionary = _this as IReadOnlyDictionary; if (roDictionary == null) { roDictionary = new ReadOnlyDictionary(_this); } return roDictionary; } // bool Insert(K key, V value) internal bool Insert(K key, V value) { IDictionary _this = JitHelpers.UnsafeCast>(this); bool replacing = _this.ContainsKey(key); _this[key] = value; return replacing; } // void Remove(K key) internal void Remove(K key) { IDictionary _this = JitHelpers.UnsafeCast>(this); bool removed = _this.Remove(key); if (!removed) { Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound")); e.SetErrorCode(__HResults.E_BOUNDS); throw e; } } // void Clear() internal void Clear() { IDictionary _this = JitHelpers.UnsafeCast>(this); _this.Clear(); } } }