using System; using System.Collections.Generic; using Confuser.Core.Services; using dnlib.DotNet; namespace Confuser.Core.API { internal class APIStore : IAPIStore { readonly ConfuserContext context; readonly RandomGenerator random; readonly SortedList> dataStores; readonly List predicates; /// /// Initializes a new instance of the class. /// /// The working context. public APIStore(ConfuserContext context) { this.context = context; random = context.Registry.GetService().GetRandomGenerator("APIStore"); dataStores = new SortedList>(); predicates = new List(); } /// public void AddStore(IDataStore dataStore) { dataStores.AddListEntry(dataStore.Priority, dataStore); } /// public void AddPredicate(IOpaquePredicateDescriptor predicate) { predicates.Add(predicate); } /// public IDataStore GetStore(MethodDef method) { for (int i = dataStores.Count - 1; i >= 0; i--) { var list = dataStores[i]; for (int j = list.Count - 1; j >= 0; i--) { if (list[j].IsUsable(method)) return list[j]; } } return null; } /// public IOpaquePredicateDescriptor GetPredicate(MethodDef method, OpaquePredicateType? type, params int[] argCount) { var randomPredicates = predicates.ToArray(); random.Shuffle(randomPredicates); foreach (var predicate in randomPredicates) { if (predicate.IsUsable(method) && (type == null || predicate.Type == type.Value) && (argCount == null || Array.IndexOf(argCount, predicate.ArgumentCount) != -1)) return predicate; } return null; } } /// /// Provides storage for API interfaces /// public interface IAPIStore { /// /// Adds the specified data store into this store. /// /// The data store. void AddStore(IDataStore dataStore); /// /// Finds a suitable data store for the specified method, with the /// specified number of keys. /// /// The method. /// The suitable data store if found, or null if not found. /// /// It should never returns null --- ConfuserEx has internal data store. /// IDataStore GetStore(MethodDef method); /// /// Adds the specified opaque predicate into this store. /// /// The opaque predicate. void AddPredicate(IOpaquePredicateDescriptor predicate); /// /// Finds a suitable opaque predicate for the specified method, with the /// specified properties. /// /// The method. /// The required type of predicate, or null if it does not matter. /// The required numbers of arguments, or null if it does not matter. /// The suitable opaque predicate if found, or null if not found. IOpaquePredicateDescriptor GetPredicate(MethodDef method, OpaquePredicateType? type, params int[] argCount); } }