aspclassic-core/AspClassic.Scripting/ScopeVariableIgnoreCase.cs
Jelle Luteijn 484dbfc9d9 progress
2022-05-15 11:19:49 +02:00

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;
}
}
}