namespace Unosquare.Swan.Networking.Ldap { using System; using System.Collections.Generic; using System.Linq; /// /// An LdapSearchResults object is returned from a synchronous search /// operation. It provides access to all results received during the /// operation (entries and exceptions). /// /// public sealed class LdapSearchResults { private readonly List _messages; private readonly int _messageId; /// /// Initializes a new instance of the class. /// /// The messages. /// The message identifier. internal LdapSearchResults(List messages, int messageId) { _messages = messages; _messageId = messageId; } /// /// Returns a count of the items in the search result. /// Returns a count of the entries and exceptions remaining in the object. /// If the search was submitted with a batch size greater than zero, /// getCount reports the number of results received so far but not enumerated /// with next(). If batch size equals zero, getCount reports the number of /// items received, since the application thread blocks until all results are /// received. /// /// /// The count. /// public int Count => new List(_messages) .Count(x => x.MessageId == _messageId && GetResponse(x) is LdapSearchResult); /// /// Reports if there are more search results. /// /// /// true if there are more search results. /// public bool HasMore() => new List(_messages) .Any(x => x.MessageId == _messageId && GetResponse(x) is LdapSearchResult); /// /// Returns the next result as an LdapEntry. /// If automatic referral following is disabled or if a referral /// was not followed, next() will throw an LdapReferralException /// when the referral is received. /// /// /// The next search result as an LdapEntry. /// /// Next - No more results. public LdapEntry Next() { var list = new List(_messages) .Where(x => x.MessageId == _messageId); foreach (var item in list) { _messages.Remove(item); var response = GetResponse(item); if (response is LdapSearchResult result) { return result.Entry; } } throw new ArgumentOutOfRangeException(nameof(Next), "No more results"); } private static LdapMessage GetResponse(RfcLdapMessage item) { switch (item.Type) { case LdapOperation.SearchResponse: return new LdapSearchResult(item); case LdapOperation.SearchResultReference: return new LdapSearchResultReference(item); default: return new LdapResponse(item); } } } }