progress
This commit is contained in:
parent
16e76d6b31
commit
484dbfc9d9
529 changed files with 113694 additions and 0 deletions
575
AspClassic.Scripting/Runtime/SymbolDictionary.cs
Normal file
575
AspClassic.Scripting/Runtime/SymbolDictionary.cs
Normal file
|
@ -0,0 +1,575 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using AspClassic.Scripting.Utils;
|
||||
|
||||
namespace AspClassic.Scripting.Runtime;
|
||||
|
||||
internal sealed class SymbolDictionary : BaseSymbolDictionary, IDictionary, ICollection, IDictionary<object, object>, ICollection<KeyValuePair<object, object>>, IAttributesCollection, IEnumerable<KeyValuePair<object, object>>, IEnumerable
|
||||
{
|
||||
private Dictionary<SymbolId, object> _data = new Dictionary<SymbolId, object>();
|
||||
|
||||
ICollection<object> IDictionary<object, object>.Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
List<object> list = new List<object>();
|
||||
lock (this)
|
||||
{
|
||||
foreach (SymbolId key in _data.Keys)
|
||||
{
|
||||
if (!(key == BaseSymbolDictionary.ObjectKeys))
|
||||
{
|
||||
list.Add(SymbolTable.IdToString(key));
|
||||
}
|
||||
}
|
||||
Dictionary<object, object> objectKeysDictionaryIfExists = GetObjectKeysDictionaryIfExists();
|
||||
if (objectKeysDictionaryIfExists != null)
|
||||
{
|
||||
list.AddRange(objectKeysDictionaryIfExists.Keys);
|
||||
return list;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ICollection<object> IDictionary<object, object>.Values
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
Dictionary<object, object> objectKeysDictionaryIfExists = GetObjectKeysDictionaryIfExists();
|
||||
if (objectKeysDictionaryIfExists == null)
|
||||
{
|
||||
return _data.Values;
|
||||
}
|
||||
List<object> list = new List<object>();
|
||||
foreach (KeyValuePair<SymbolId, object> datum in _data)
|
||||
{
|
||||
if (!(datum.Key == BaseSymbolDictionary.ObjectKeys))
|
||||
{
|
||||
list.Add(datum.Value);
|
||||
}
|
||||
}
|
||||
foreach (object value in objectKeysDictionaryIfExists.Values)
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public object this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
string text = key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
if (_data.TryGetValue(SymbolTable.StringToId(text), out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<object, object> objectKeysDictionaryIfExists = GetObjectKeysDictionaryIfExists();
|
||||
if (objectKeysDictionaryIfExists != null)
|
||||
{
|
||||
return objectKeysDictionaryIfExists[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new KeyNotFoundException($"'{key}'");
|
||||
}
|
||||
set
|
||||
{
|
||||
string text = key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
_data[SymbolTable.StringToId(text)] = value;
|
||||
return;
|
||||
}
|
||||
Dictionary<object, object> objectKeysDictionary = GetObjectKeysDictionary();
|
||||
objectKeysDictionary[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
int num = _data.Count;
|
||||
Dictionary<object, object> objectKeysDictionaryIfExists = GetObjectKeysDictionaryIfExists();
|
||||
if (objectKeysDictionaryIfExists != null)
|
||||
{
|
||||
num += objectKeysDictionaryIfExists.Count - 1;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
object IAttributesCollection.this[SymbolId name]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return _data[name];
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_data[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<SymbolId, object> SymbolAttributes
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (GetObjectKeysDictionaryIfExists() == null)
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
Dictionary<SymbolId, object> dictionary = new Dictionary<SymbolId, object>();
|
||||
foreach (KeyValuePair<SymbolId, object> datum in _data)
|
||||
{
|
||||
if (!(datum.Key == BaseSymbolDictionary.ObjectKeys))
|
||||
{
|
||||
dictionary.Add(datum.Key, datum.Value);
|
||||
}
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<object> Keys => AsObjectKeyedDictionary().Keys;
|
||||
|
||||
public bool IsFixedSize => false;
|
||||
|
||||
ICollection IDictionary.Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
List<object> list = new List<object>();
|
||||
lock (this)
|
||||
{
|
||||
foreach (SymbolId key in _data.Keys)
|
||||
{
|
||||
if (!(key == BaseSymbolDictionary.ObjectKeys))
|
||||
{
|
||||
list.Add(SymbolTable.IdToString(key));
|
||||
}
|
||||
}
|
||||
Dictionary<object, object> objectKeysDictionaryIfExists = GetObjectKeysDictionaryIfExists();
|
||||
if (objectKeysDictionaryIfExists != null)
|
||||
{
|
||||
list.AddRange(objectKeysDictionaryIfExists.Keys);
|
||||
return list;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ICollection IDictionary.Values
|
||||
{
|
||||
get
|
||||
{
|
||||
List<object> list = new List<object>();
|
||||
lock (this)
|
||||
{
|
||||
foreach (KeyValuePair<SymbolId, object> datum in _data)
|
||||
{
|
||||
if (!(datum.Key == BaseSymbolDictionary.ObjectKeys))
|
||||
{
|
||||
list.Add(datum.Value);
|
||||
}
|
||||
}
|
||||
Dictionary<object, object> objectKeysDictionaryIfExists = GetObjectKeysDictionaryIfExists();
|
||||
if (objectKeysDictionaryIfExists != null)
|
||||
{
|
||||
list.AddRange(objectKeysDictionaryIfExists.Values);
|
||||
return list;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object IDictionary.this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return AsObjectKeyedDictionary()[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
AsObjectKeyedDictionary()[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSynchronized => true;
|
||||
|
||||
public object SyncRoot => this;
|
||||
|
||||
public SymbolDictionary()
|
||||
{
|
||||
}
|
||||
|
||||
public SymbolDictionary(IAttributesCollection from)
|
||||
{
|
||||
lock (from)
|
||||
{
|
||||
foreach (KeyValuePair<object, object> item in from)
|
||||
{
|
||||
AsObjectKeyedDictionary().Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<object, object> GetObjectKeysDictionary()
|
||||
{
|
||||
Dictionary<object, object> dictionary = GetObjectKeysDictionaryIfExists();
|
||||
if (dictionary == null)
|
||||
{
|
||||
dictionary = new Dictionary<object, object>();
|
||||
_data.Add(BaseSymbolDictionary.ObjectKeys, dictionary);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private Dictionary<object, object> GetObjectKeysDictionaryIfExists()
|
||||
{
|
||||
if (_data.TryGetValue(BaseSymbolDictionary.ObjectKeys, out var value))
|
||||
{
|
||||
return (Dictionary<object, object>)value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void IDictionary<object, object>.Add(object key, object value)
|
||||
{
|
||||
string text = key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
_data.Add(SymbolTable.StringToId(text), value);
|
||||
return;
|
||||
}
|
||||
Dictionary<object, object> objectKeysDictionary = GetObjectKeysDictionary();
|
||||
objectKeysDictionary[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDictionary<object, object>.ContainsKey(object key)
|
||||
{
|
||||
string text = key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
if (!SymbolTable.StringHasId(text))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return _data.ContainsKey(SymbolTable.StringToId(text));
|
||||
}
|
||||
return GetObjectKeysDictionaryIfExists()?.ContainsKey(key) ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDictionary<object, object>.Remove(object key)
|
||||
{
|
||||
string text = key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
return _data.Remove(SymbolTable.StringToId(text));
|
||||
}
|
||||
return GetObjectKeysDictionaryIfExists()?.Remove(key) ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDictionary<object, object>.TryGetValue(object key, out object value)
|
||||
{
|
||||
string text = key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
return _data.TryGetValue(SymbolTable.StringToId(text), out value);
|
||||
}
|
||||
value = null;
|
||||
return GetObjectKeysDictionaryIfExists()?.TryGetValue(key, out value) ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<object, object> item)
|
||||
{
|
||||
string text = item.Key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
_data.Add(SymbolTable.StringToId(text), item.Value);
|
||||
return;
|
||||
}
|
||||
Dictionary<object, object> objectKeysDictionary = GetObjectKeysDictionary();
|
||||
objectKeysDictionary[item.Key] = item.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_data.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<object, object> item)
|
||||
{
|
||||
if (AsObjectKeyedDictionary().TryGetValue(item.Key, out var value) && value == item.Value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
|
||||
{
|
||||
ContractUtils.RequiresNotNull(array, "array");
|
||||
lock (this)
|
||||
{
|
||||
ContractUtils.RequiresArrayRange(array, arrayIndex, Count, "arrayIndex", "array");
|
||||
foreach (KeyValuePair<object, object> item in (IEnumerable<KeyValuePair<object, object>>)this)
|
||||
{
|
||||
array[arrayIndex++] = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<object, object> item)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (item.Key is string text && AsObjectKeyedDictionary().TryGetValue(text, out var value) && value == item.Value)
|
||||
{
|
||||
_data.Remove(SymbolTable.StringToId(text));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<object, object>> IEnumerable<KeyValuePair<object, object>>.GetEnumerator()
|
||||
{
|
||||
bool lockTaken = false;
|
||||
SymbolDictionary obj2 = default(SymbolDictionary);
|
||||
try
|
||||
{
|
||||
SymbolDictionary obj;
|
||||
obj2 = (obj = this);
|
||||
Monitor.Enter(obj, ref lockTaken);
|
||||
foreach (KeyValuePair<SymbolId, object> o in _data)
|
||||
{
|
||||
KeyValuePair<SymbolId, object> keyValuePair = o;
|
||||
if (!(keyValuePair.Key == BaseSymbolDictionary.ObjectKeys))
|
||||
{
|
||||
KeyValuePair<SymbolId, object> keyValuePair2 = o;
|
||||
string key = SymbolTable.IdToString(keyValuePair2.Key);
|
||||
KeyValuePair<SymbolId, object> keyValuePair3 = o;
|
||||
yield return new KeyValuePair<object, object>(key, keyValuePair3.Value);
|
||||
}
|
||||
}
|
||||
Dictionary<object, object> objData = GetObjectKeysDictionaryIfExists();
|
||||
if (objData == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
foreach (KeyValuePair<object, object> item in objData)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockTaken)
|
||||
{
|
||||
Monitor.Exit(obj2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
foreach (KeyValuePair<SymbolId, object> o in _data)
|
||||
{
|
||||
KeyValuePair<SymbolId, object> keyValuePair = o;
|
||||
if (!(keyValuePair.Key == BaseSymbolDictionary.ObjectKeys))
|
||||
{
|
||||
KeyValuePair<SymbolId, object> keyValuePair2 = o;
|
||||
yield return SymbolTable.IdToString(keyValuePair2.Key);
|
||||
}
|
||||
}
|
||||
IDictionary<object, object> objData = GetObjectKeysDictionaryIfExists();
|
||||
if (objData == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
foreach (object key in objData.Keys)
|
||||
{
|
||||
yield return key;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(SymbolId name, object value)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_data.Add(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsKey(SymbolId name)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return _data.ContainsKey(name);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(SymbolId name)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return _data.Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetValue(SymbolId name, out object value)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return _data.TryGetValue(name, out value);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddObjectKey(object name, object value)
|
||||
{
|
||||
AsObjectKeyedDictionary().Add(name, value);
|
||||
}
|
||||
|
||||
public bool ContainsObjectKey(object name)
|
||||
{
|
||||
return AsObjectKeyedDictionary().ContainsKey(name);
|
||||
}
|
||||
|
||||
public bool RemoveObjectKey(object name)
|
||||
{
|
||||
return AsObjectKeyedDictionary().Remove(name);
|
||||
}
|
||||
|
||||
public bool TryGetObjectValue(object name, out object value)
|
||||
{
|
||||
return AsObjectKeyedDictionary().TryGetValue(name, out value);
|
||||
}
|
||||
|
||||
public IDictionary<object, object> AsObjectKeyedDictionary()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void IDictionary.Add(object key, object value)
|
||||
{
|
||||
AsObjectKeyedDictionary().Add(key, value);
|
||||
}
|
||||
|
||||
public bool Contains(object key)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return AsObjectKeyedDictionary().ContainsKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator()
|
||||
{
|
||||
Dictionary<object, object> objectKeysDictionaryIfExists = GetObjectKeysDictionaryIfExists();
|
||||
if (objectKeysDictionaryIfExists == null)
|
||||
{
|
||||
return new TransformDictionaryEnumerator(_data);
|
||||
}
|
||||
List<IDictionaryEnumerator> list = new List<IDictionaryEnumerator>();
|
||||
list.Add(new TransformDictionaryEnumerator(_data));
|
||||
Dictionary<object, object>.Enumerator enumerator = objectKeysDictionaryIfExists.GetEnumerator();
|
||||
list.Add(enumerator);
|
||||
return new DictionaryUnionEnumerator(list);
|
||||
}
|
||||
|
||||
void IDictionary.Remove(object key)
|
||||
{
|
||||
string text = key as string;
|
||||
lock (this)
|
||||
{
|
||||
if (text != null)
|
||||
{
|
||||
_data.Remove(SymbolTable.StringToId(text));
|
||||
}
|
||||
else
|
||||
{
|
||||
GetObjectKeysDictionaryIfExists()?.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
ContractUtils.RequiresNotNull(array, "array");
|
||||
lock (this)
|
||||
{
|
||||
ContractUtils.RequiresListRange(array, index, Count, "index", "array");
|
||||
IEnumerator enumerator = GetEnumerator();
|
||||
try
|
||||
{
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
object current = enumerator.Current;
|
||||
array.SetValue(current, index++);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
IDisposable disposable = enumerator as IDisposable;
|
||||
if (disposable != null)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue