175 lines
3 KiB
C#
175 lines
3 KiB
C#
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<string, ScopeVariable> _overflow;
|
|
|
|
public bool HasValue
|
|
{
|
|
get
|
|
{
|
|
if (_firstVariable.HasValue)
|
|
{
|
|
return true;
|
|
}
|
|
if (_overflow != null)
|
|
{
|
|
lock (_overflow)
|
|
{
|
|
foreach (KeyValuePair<string, ScopeVariable> 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<string, ScopeVariable> 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<string, ScopeVariable> 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<string> list)
|
|
{
|
|
if (_firstVariable.HasValue)
|
|
{
|
|
list.Add(_firstCasing);
|
|
}
|
|
if (_overflow == null)
|
|
{
|
|
return;
|
|
}
|
|
lock (_overflow)
|
|
{
|
|
foreach (KeyValuePair<string, ScopeVariable> item in _overflow)
|
|
{
|
|
if (item.Value.HasValue)
|
|
{
|
|
list.Add(item.Key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void AddItems(List<KeyValuePair<string, object>> list)
|
|
{
|
|
if (_firstVariable.TryGetValue(out var value))
|
|
{
|
|
list.Add(new KeyValuePair<string, object>(_firstCasing, value));
|
|
}
|
|
if (_overflow == null)
|
|
{
|
|
return;
|
|
}
|
|
lock (_overflow)
|
|
{
|
|
foreach (KeyValuePair<string, ScopeVariable> item in _overflow)
|
|
{
|
|
if (item.Value.TryGetValue(out value))
|
|
{
|
|
list.Add(new KeyValuePair<string, object>(item.Key, value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private ScopeVariable GetStorageSlow(string name)
|
|
{
|
|
if (_overflow == null)
|
|
{
|
|
Interlocked.CompareExchange(ref _overflow, new Dictionary<string, ScopeVariable>(), null);
|
|
}
|
|
lock (_overflow)
|
|
{
|
|
if (!_overflow.TryGetValue(name, out var value))
|
|
{
|
|
value = (_overflow[name] = new ScopeVariable());
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
}
|