();
this._elements.AddRange(this._source.Split(this._delimiters.ToCharArray()));
this.RemoveEmptyStrings();
result = this._elements[0];
this._elements.RemoveAt(0);
this._source = this._source.Remove(this._source.IndexOf(result, StringComparison.Ordinal), result.Length);
this._source = this._source.TrimStart(this._delimiters.ToCharArray());
return result;
}
private void RemoveEmptyStrings() {
for(Int32 index = 0; index < this._elements.Count; index++) {
if(this._elements[index] != String.Empty) {
continue;
}
this._elements.RemoveAt(index);
index--;
}
}
private void Tokenize() {
String tempstr = this._source;
if(tempstr.IndexOfAny(this._delimiters.ToCharArray()) < 0 && tempstr.Length > 0) {
this._elements.Add(tempstr);
} else if(tempstr.IndexOfAny(this._delimiters.ToCharArray()) < 0 && tempstr.Length <= 0) {
return;
}
while(tempstr.IndexOfAny(this._delimiters.ToCharArray()) >= 0) {
if(tempstr.IndexOfAny(this._delimiters.ToCharArray()) == 0) {
if(tempstr.Length > 1) {
this._elements.Add(tempstr.Substring(0, 1));
tempstr = tempstr.Substring(1);
} else {
tempstr = String.Empty;
}
} else {
String toks = tempstr.Substring(0, tempstr.IndexOfAny(this._delimiters.ToCharArray()));
this._elements.Add(toks);
this._elements.Add(tempstr.Substring(toks.Length, 1));
tempstr = tempstr.Length > toks.Length + 1 ? tempstr.Substring(toks.Length + 1) : String.Empty;
}
}
if(tempstr.Length > 0) {
this._elements.Add(tempstr);
}
}
}
///
/// Represents an Ldap Matching Rule Assertion.
///
/// MatchingRuleAssertion ::= SEQUENCE {
/// matchingRule [1] MatchingRuleId OPTIONAL,
/// type [2] AttributeDescription OPTIONAL,
/// matchValue [3] AssertionValue,
/// dnAttributes [4] BOOLEAN DEFAULT FALSE }
///
///
internal class RfcMatchingRuleAssertion : Asn1Sequence {
public RfcMatchingRuleAssertion(
String matchingRule,
String type,
SByte[] matchValue,
Asn1Boolean dnAttributes = null)
: base(4) {
if(matchingRule != null) {
this.Add(new Asn1Tagged(new Asn1Identifier(1), new Asn1OctetString(matchingRule), false));
}
if(type != null) {
this.Add(new Asn1Tagged(new Asn1Identifier(2), new Asn1OctetString(type), false));
}
this.Add(new Asn1Tagged(new Asn1Identifier(3), new Asn1OctetString(matchValue), false));
// if dnAttributes if false, that is the default value and we must not
// encode it. (See RFC 2251 5.1 number 4)
if(dnAttributes != null && dnAttributes.BooleanValue()) {
this.Add(new Asn1Tagged(new Asn1Identifier(4), dnAttributes, false));
}
}
}
///
/// The AttributeDescriptionList is used to list attributes to be returned in
/// a search request.
///
/// AttributeDescriptionList ::= SEQUENCE OF
/// AttributeDescription
///
///
internal class RfcAttributeDescriptionList : Asn1SequenceOf {
public RfcAttributeDescriptionList(String[] attrs)
: base(attrs?.Length ?? 0) {
if(attrs == null) {
return;
}
foreach(String attr in attrs) {
this.Add(attr);
}
}
}
///
/// Represents an Ldap Search Request.
///
/// SearchRequest ::= [APPLICATION 3] SEQUENCE {
/// baseObject LdapDN,
/// scope ENUMERATED {
/// baseObject (0),
/// singleLevel (1),
/// wholeSubtree (2) },
/// derefAliases ENUMERATED {
/// neverDerefAliases (0),
/// derefInSearching (1),
/// derefFindingBaseObj (2),
/// derefAlways (3) },
/// sizeLimit INTEGER (0 .. maxInt),
/// timeLimit INTEGER (0 .. maxInt),
/// typesOnly BOOLEAN,
/// filter Filter,
/// attributes AttributeDescriptionList }
///
///
///
///
internal class RfcSearchRequest : Asn1Sequence, IRfcRequest {
public RfcSearchRequest(
String basePath,
LdapScope scope,
Int32 derefAliases,
Int32 sizeLimit,
Int32 timeLimit,
Boolean typesOnly,
String filter,
String[] attributes)
: base(8) {
this.Add(basePath);
this.Add(new Asn1Enumerated(scope));
this.Add(new Asn1Enumerated(derefAliases));
this.Add(new Asn1Integer(sizeLimit));
this.Add(new Asn1Integer(timeLimit));
this.Add(new Asn1Boolean(typesOnly));
this.Add(new RfcFilter(filter));
this.Add(new RfcAttributeDescriptionList(attributes));
}
public override Asn1Identifier GetIdentifier() => new Asn1Identifier(LdapOperation.SearchRequest);
public String GetRequestDN() => ((Asn1OctetString)this.Get(0)).StringValue();
}
///
/// Represents an Ldap Substring Filter.
///
/// SubstringFilter ::= SEQUENCE {
/// type AttributeDescription,
/// -- at least one must be present
/// substrings SEQUENCE OF CHOICE {
/// initial [0] LdapString,
/// any [1] LdapString,
/// final [2] LdapString } }
///
///
///
internal class RfcSubstringFilter : Asn1Sequence {
public RfcSubstringFilter(String type, Asn1Object substrings)
: base(2) {
this.Add(type);
this.Add(substrings);
}
}
///
/// Represents an Ldap Attribute Value Assertion.
///
/// AttributeValueAssertion ::= SEQUENCE {
/// attributeDesc AttributeDescription,
/// assertionValue AssertionValue }
///
///
///
internal class RfcAttributeValueAssertion : Asn1Sequence {
public RfcAttributeValueAssertion(String ad, SByte[] av)
: base(2) {
this.Add(ad);
this.Add(new Asn1OctetString(av));
}
public String AttributeDescription => ((Asn1OctetString)this.Get(0)).StringValue();
public SByte[] AssertionValue => ((Asn1OctetString)this.Get(1)).ByteValue();
}
/// Encapsulates an Ldap Bind properties.
internal class BindProperties {
///
/// Initializes a new instance of the class.
///
/// The version.
/// The dn.
/// The method.
/// if set to true [anonymous].
public BindProperties(
Int32 version,
String dn,
String method,
Boolean anonymous) {
this.ProtocolVersion = version;
this.AuthenticationDN = dn;
this.AuthenticationMethod = method;
this.Anonymous = anonymous;
}
public Int32 ProtocolVersion {
get;
}
public String AuthenticationDN {
get;
}
public String AuthenticationMethod {
get;
}
public Boolean Anonymous {
get;
}
}
}