using System; using System.Collections.Generic; using System.Threading; namespace AspClassic.Scripting; public sealed class ScopeVariableIgnoreCase : IScopeVariable, IWeakReferencable { private readonly string _firstCasing; private readonly ScopeVariable _firstVariable; private WeakReference _weakref; private Dictionary _overflow; public bool HasValue { get { if (_firstVariable.HasValue) { return true; } if (_overflow != null) { lock (_overflow) { foreach (KeyValuePair item in _overflow) { if (item.Value.HasValue) { return true; } } } } return false; } } public WeakReference WeakReference { get { if (_weakref == null) { _weakref = new WeakReference(this); } return _weakref; } } internal ScopeVariableIgnoreCase(string casing) { _firstCasing = casing; _firstVariable = new ScopeVariable(); } public bool TryGetValue(out dynamic value) { if (_firstVariable.TryGetValue(out var value2)) { value = value2; return true; } if (_overflow != null) { lock (_overflow) { foreach (KeyValuePair item in _overflow) { if (item.Value.TryGetValue(out value2)) { value = value2; return true; } } } } value = null; return false; } public void SetValue(object value) { _firstVariable.SetValue(value); } public bool DeleteValue() { bool flag = _firstVariable.DeleteValue(); if (_overflow != null) { lock (_overflow) { foreach (KeyValuePair item in _overflow) { flag = item.Value.DeleteValue() || flag; } return flag; } } return flag; } internal ScopeVariable GetCaseSensitiveStorage(string name) { if (name == _firstCasing) { return _firstVariable; } return GetStorageSlow(name); } internal void AddNames(List list) { if (_firstVariable.HasValue) { list.Add(_firstCasing); } if (_overflow == null) { return; } lock (_overflow) { foreach (KeyValuePair item in _overflow) { if (item.Value.HasValue) { list.Add(item.Key); } } } } internal void AddItems(List> list) { if (_firstVariable.TryGetValue(out var value)) { list.Add(new KeyValuePair(_firstCasing, value)); } if (_overflow == null) { return; } lock (_overflow) { foreach (KeyValuePair item in _overflow) { if (item.Value.TryGetValue(out value)) { list.Add(new KeyValuePair(item.Key, value)); } } } } private ScopeVariable GetStorageSlow(string name) { if (_overflow == null) { Interlocked.CompareExchange(ref _overflow, new Dictionary(), null); } lock (_overflow) { if (!_overflow.TryGetValue(name, out var value)) { value = (_overflow[name] = new ScopeVariable()); } return value; } } }