/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using System.Collections; using System.Collections.Generic; using System.ComponentModel; namespace OpenSearch.Client { public abstract class IsADictionaryBase : IIsADictionary { protected IsADictionaryBase() => BackingDictionary = new Dictionary(); protected IsADictionaryBase(IDictionary backingDictionary) { // ReSharper disable VirtualMemberCallInConstructor if (backingDictionary != null) foreach (var key in backingDictionary.Keys) ValidateKey(Sanitize(key)); // ReSharper enable VirtualMemberCallInConstructor BackingDictionary = backingDictionary != null ? new Dictionary(backingDictionary) : new Dictionary(); } public TValue this[TKey key] { get => BackingDictionary[Sanitize(key)]; set => BackingDictionary[ValidateKey(Sanitize(key))] = value; } protected Dictionary BackingDictionary { get; } int ICollection>.Count => BackingDictionary.Count; bool ICollection>.IsReadOnly => Self.IsReadOnly; TValue IDictionary.this[TKey key] { get => BackingDictionary[Sanitize(key)]; set => BackingDictionary[ValidateKey(Sanitize(key))] = value; } ICollection IDictionary.Keys => BackingDictionary.Keys; private ICollection> Self => BackingDictionary; ICollection IDictionary.Values => BackingDictionary.Values; void ICollection>.Add(KeyValuePair item) { ValidateKey(Sanitize(item.Key)); Self.Add(item); } void ICollection>.Clear() => BackingDictionary.Clear(); [EditorBrowsable(EditorBrowsableState.Never)] bool ICollection>.Contains(KeyValuePair item) => Self.Contains(item); void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) => Self.CopyTo(array, arrayIndex); bool ICollection>.Remove(KeyValuePair item) => Self.Remove(item); void IDictionary.Add(TKey key, TValue value) => BackingDictionary.Add(ValidateKey(Sanitize(key)), value); [EditorBrowsable(EditorBrowsableState.Never)] bool IDictionary.ContainsKey(TKey key) => BackingDictionary.ContainsKey(Sanitize(key)); bool IDictionary.Remove(TKey key) => BackingDictionary.Remove(Sanitize(key)); bool IDictionary.TryGetValue(TKey key, out TValue value) => BackingDictionary.TryGetValue(Sanitize(key), out value); IEnumerator IEnumerable.GetEnumerator() => BackingDictionary.GetEnumerator(); IEnumerator> IEnumerable>.GetEnumerator() => BackingDictionary.GetEnumerator(); protected virtual TKey ValidateKey(TKey key) => key; protected virtual TKey Sanitize(TKey key) => key; } }