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);
}
}
}
}