diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-06-26 19:34:14 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-06-26 19:34:14 +0700 |
commit | c8bba37510f01f116fea99204e934d35863a9d2b (patch) | |
tree | 799f39da3e8b2dc53a94b4f5e735626a83c8f7ef | |
parent | Reorganize test vector tests (diff) | |
download | BouncyCastle.NET-ed25519-c8bba37510f01f116fea99204e934d35863a9d2b.tar.xz |
Add store/selector API
-rw-r--r-- | crypto/src/util/collections/CollectionUtilities.cs | 38 | ||||
-rw-r--r-- | crypto/src/util/collections/ISelector.cs | 16 | ||||
-rw-r--r-- | crypto/src/util/collections/IStore.cs | 15 | ||||
-rw-r--r-- | crypto/src/util/collections/StoreImpl.cs | 25 |
4 files changed, 90 insertions, 4 deletions
diff --git a/crypto/src/util/collections/CollectionUtilities.cs b/crypto/src/util/collections/CollectionUtilities.cs index 37551e5b3..426700903 100644 --- a/crypto/src/util/collections/CollectionUtilities.cs +++ b/crypto/src/util/collections/CollectionUtilities.cs @@ -15,6 +15,36 @@ namespace Org.BouncyCastle.Utilities.Collections } } + public static void CollectMatches<T>(ICollection<T> matches, ISelector<T> selector, params IStore<T>[] stores) + { + CollectMatches(matches, selector, stores); + } + + public static void CollectMatches<T>(ICollection<T> matches, ISelector<T> selector, + IEnumerable<IStore<T>> stores) + { + if (matches == null) + throw new ArgumentNullException(nameof(matches)); + if (stores == null) + return; + + foreach (var store in stores) + { + if (store == null) + continue; + + foreach (T match in store.EnumerateMatches(selector)) + { + matches.Add(match); + } + } + } + + public static IStore<T> CreateStore<T>(IEnumerable<T> contents) + { + return new StoreImpl<T>(contents); + } + public static IEnumerable Proxy(IEnumerable e) { return new EnumerableProxy(e); @@ -48,18 +78,18 @@ namespace Org.BouncyCastle.Utilities.Collections return e.Current; } - public static string ToString(IEnumerable c) + public static string ToString<T>(IEnumerable<T> c) { - IEnumerator e = c.GetEnumerator(); + IEnumerator<T> e = c.GetEnumerator(); if (!e.MoveNext()) return "[]"; StringBuilder sb = new StringBuilder("["); - sb.Append(e.Current.ToString()); + sb.Append(e.Current); while (e.MoveNext()) { sb.Append(", "); - sb.Append(e.Current.ToString()); + sb.Append(e.Current); } sb.Append(']'); return sb.ToString(); diff --git a/crypto/src/util/collections/ISelector.cs b/crypto/src/util/collections/ISelector.cs new file mode 100644 index 000000000..186b922d3 --- /dev/null +++ b/crypto/src/util/collections/ISelector.cs @@ -0,0 +1,16 @@ +using System; + +namespace Org.BouncyCastle.Utilities.Collections +{ + /// <summary>Interface for matching objects in an <see cref="IStore{T}"/>.</summary> + /// <typeparam name="T">The contravariant type of selectable objects.</typeparam> + public interface ISelector<in T> + : ICloneable + { + /// <summary>Match the passed in object, returning true if it would be selected by this selector, false + /// otherwise.</summary> + /// <param name="candidate">The object to be matched.</param> + /// <returns><code>true</code> if the objects is matched by this selector, false otherwise.</returns> + bool Match(T candidate); + } +} diff --git a/crypto/src/util/collections/IStore.cs b/crypto/src/util/collections/IStore.cs new file mode 100644 index 000000000..12c19aaf4 --- /dev/null +++ b/crypto/src/util/collections/IStore.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Org.BouncyCastle.Utilities.Collections +{ + /// <summary>A generic interface describing a simple store of objects.</summary> + /// <typeparam name="T">The covariant type of stored objects.</typeparam> + public interface IStore<out T> + { + /// <summary>Enumerate the (possibly empty) collection of objects matched by the given selector.</summary> + /// <param name="selector">The <see cref="ISelector{T}"/> used to select matching objects.</param> + /// <returns>An <see cref="IEnumerable{T}"/> of the matching objects.</returns> + IEnumerable<T> EnumerateMatches(ISelector<T> selector); + } +} diff --git a/crypto/src/util/collections/StoreImpl.cs b/crypto/src/util/collections/StoreImpl.cs new file mode 100644 index 000000000..3a7135007 --- /dev/null +++ b/crypto/src/util/collections/StoreImpl.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace Org.BouncyCastle.Utilities.Collections +{ + internal sealed class StoreImpl<T> + : IStore<T> + { + private readonly List<T> m_contents; + + internal StoreImpl(IEnumerable<T> e) + { + m_contents = new List<T>(e); + } + + IEnumerable<T> IStore<T>.EnumerateMatches(ISelector<T> selector) + { + foreach (T candidate in m_contents) + { + if (selector == null || selector.Match(candidate)) + yield return candidate; + } + } + } +} |