using System; using System.Collections.Generic; using AspClassic.Scripting.Utils; namespace AspClassic.Scripting; public static class SymbolTable { private const int InitialTableSize = 256; internal const int CaseVersionMask = -16777216; internal const int CaseVersionIncrement = 16777216; private static readonly object _lockObj = new object(); private static readonly Dictionary _idDict = new Dictionary(256); private static readonly Dictionary _invariantDict = new Dictionary(256, StringComparer.OrdinalIgnoreCase); private static readonly Dictionary _fieldDict = CreateFieldDictionary(); private static int _nextCaseInsensitiveId = 1; private static Dictionary CreateFieldDictionary() { Dictionary dictionary = new Dictionary(256); dictionary[0] = null; return dictionary; } public static SymbolId StringToId(string value) { ContractUtils.RequiresNotNull(value, "value"); int value2; lock (_lockObj) { if (!_idDict.TryGetValue(value, out value2)) { if (!_invariantDict.TryGetValue(value, out value2)) { if (_nextCaseInsensitiveId == 16777215) { throw Error.CantAddIdentifier(value); } value2 = _nextCaseInsensitiveId++ | 0x1000000; } else { if (((uint)value2 & -16777216) == -16777216) { throw Error.CantAddCasing(value); } value2 += 16777216; } _invariantDict[value] = value2; _idDict[value] = value2; _fieldDict[value2] = value; } } return new SymbolId(value2); } public static SymbolId StringToCaseInsensitiveId(string value) { return StringToId(value).CaseInsensitiveIdentifier; } public static SymbolId[] QualifiedStringToIds(string values) { if (values != null) { string[] array = values.Split('.'); SymbolId[] array2 = new SymbolId[array.Length]; for (int i = 0; i < array.Length; i++) { ref SymbolId reference = ref array2[i]; reference = StringToId(array[i]); } return array2; } return null; } public static string IdToString(SymbolId id) { lock (_fieldDict) { if (id.IsCaseInsensitive) { return _fieldDict[id.Id | 0x1000000]; } return _fieldDict[id.Id]; } } public static bool ContainsId(SymbolId id) { lock (_fieldDict) { if (id.IsCaseInsensitive) { return _fieldDict.ContainsKey(id.Id | 0x1000000); } return _fieldDict.ContainsKey(id.Id); } } public static string[] IdsToStrings(IList ids) { string[] array = new string[ids.Count]; for (int i = 0; i < ids.Count; i++) { if (ids[i] == SymbolId.Empty) { array[i] = null; } else { array[i] = IdToString(ids[i]); } } return array; } public static SymbolId[] StringsToIds(IList values) { SymbolId[] array = new SymbolId[values.Count]; for (int i = 0; i < values.Count; i++) { if (values[i] == null) { ref SymbolId reference = ref array[i]; reference = SymbolId.Empty; } else { ref SymbolId reference2 = ref array[i]; reference2 = StringToId(values[i]); } } return array; } public static bool StringHasId(string symbol) { ContractUtils.RequiresNotNull(symbol, "symbol"); lock (_lockObj) { return _idDict.ContainsKey(symbol); } } public static SymbolId StringToIdOrEmpty(string value) { if (value == null) { return SymbolId.Empty; } return StringToId(value); } }