private int InternalLastIndexOf(ASCIIString value, int startIndex, int count, bool ignoreCase) { Debug.Assert(value != null); Debug.Assert(startIndex >= 0); Debug.Assert(count <= this.Length - startIndex); int matchLength = value.Length; int matchChars = matchLength - 1; for (int i = (startIndex + count) - 1; i >= startIndex; i--) { ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i]; ASCIIChar toMatch = ignoreCase ? ASCIIChar.ToLower(value[matchChars]) : value[matchChars]; if (curr == toMatch) { matchChars--; if (matchChars == -1) { return(i); } continue; } matchChars = matchLength - 1; } return(-1); }
private int InternalIndexOf(ASCIIString value, int startIndex, int count, bool ignoreCase) { Debug.Assert(value != null); Debug.Assert(startIndex >= 0 && startIndex < this.Length); Debug.Assert(count <= this.Length - startIndex); int matchChars = 0; int matchLength = value.Length; for (int i = startIndex; i < startIndex + count; i++) { ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i]; ASCIIChar toMatch = ignoreCase ? ASCIIChar.ToLower(value[matchChars]) : value[matchChars]; if (curr == toMatch) { matchChars++; if (matchChars == matchLength) { return(i - (matchLength - 1)); } continue; } matchChars = 0; } return(-1); }
/// <summary> /// Returns a copy of this string converted to uppercase. /// </summary> /// <returns></returns> public ASCIIString ToUpper() { ASCIIChar[] converted = new ASCIIChar[this.Length]; for (int i = 0; i < this.Length; i++) { converted[i] = ASCIIChar.ToUpper(this.asciiChars[i]); } return(new ASCIIString(converted)); }
/// <summary> /// Initializes a new instance of the <see cref="ASCIIString"/> class to the value indicated by a specified ASCII character repeated a specified number of times. /// </summary> /// <param name="c">An ASCII character.</param> /// <param name="count">The number of times <paramref name="c"/> occurs.</param> public ASCIIString(ASCIIChar c, int count) { if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } if (count == 0) { this.asciiChars = Array.Empty <ASCIIChar>(); return; } asciiChars = new ASCIIChar[count]; ArrayExtensions.RapidFill(asciiChars, c); }
/// <summary> /// Copies the characters in a specified substring in this instance to an ASCII character array. /// </summary> /// <param name="startIndex">The starting position of a substring in this instance.</param> /// <param name="length">The length of the substring in this instance.</param> public ASCIIChar[] ToCharArray(int startIndex, int length) { if ((startIndex + length) > this.asciiChars.Length) { throw new ArgumentOutOfRangeException(nameof(startIndex), "The specified substring is out of bounds of the string."); } ASCIIChar[] retChars = new ASCIIChar[length]; for (int i = 0; i < length; i++) { retChars[i] = this.asciiChars[startIndex + i]; } return(retChars); }
/// <summary> /// Reports the zero-based index of the first occurence of the specified character in the current <see cref="ASCIIString"/> object. /// Parameters specify the starting search position in the current string, the number of character in the current string to search, and whether to ignore case. /// </summary> /// <param name="value">The character to seek.</param> /// <param name="startIndex">The search starting position.</param> /// <param name="count">The number of character positions to examine.</param> /// <param name="ignoreCase">True to ignore case; otherwise, false.</param> public int IndexOf(ASCIIChar value, int startIndex, int count, bool ignoreCase = false) { if (startIndex < 0 || startIndex >= this.Length) { throw new ArgumentOutOfRangeException(nameof(startIndex)); } if (count < 0 || count > this.Length - startIndex) { throw new ArgumentOutOfRangeException(nameof(count)); } if (count == 0) { return(-1); } return(InternalIndexOf(value, startIndex, count, ignoreCase)); }
private int InternalLastIndexOf(ASCIIChar value, int startIndex, int count, bool ignoreCase) { Debug.Assert(startIndex >= 0 && startIndex < this.Length); Debug.Assert(count <= this.Length - startIndex); ASCIIChar toMatch = ignoreCase ? ASCIIChar.ToLower(value) : value; for (int i = (startIndex + count) - 1; i >= startIndex; i--) { ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i]; if (curr == toMatch) { return(i); } } return(-1); }
/// <summary> /// Reports the zero-based index of the first occurence of the specified character in the current <see cref="ASCIIString"/> object. /// Parameters specify the starting search position in the current string, the number of character in the current string to search, and whether to ignore case. /// </summary> /// <param name="value">The character to seek.</param> /// <param name="startIndex">The search starting position.</param> /// <param name="ignoreCase">True to ignore case; otherwise, false.</param> public int IndexOf(ASCIIChar value, int startIndex, bool ignoreCase = false) { return(IndexOf(value, startIndex, this.Length, ignoreCase)); }
private int InternalLastIndexOfAny(ASCIIChar[] anyOf, int startIndex, int count, bool ignoreCase) { Debug.Assert(anyOf != null && anyOf.Length > 0); Debug.Assert(startIndex >= 0 && startIndex < this.Length); Debug.Assert(count <= this.Length - startIndex); ASCIIChar match0, match1, match2; int startAt = (startIndex + count) - 1; int endAt = startIndex; switch (anyOf.Length) { case 1: Debug.Assert(anyOf != null); match0 = ignoreCase ? ASCIIChar.ToLower(anyOf[0]) : anyOf[0]; for (int i = startAt; i >= endAt; i--) { ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i]; if (curr == match0) { return(i); } } break; case 2: Debug.Assert(anyOf != null); match0 = ignoreCase ? ASCIIChar.ToLower(anyOf[0]) : anyOf[0]; match1 = ignoreCase ? ASCIIChar.ToLower(anyOf[1]) : anyOf[1]; for (int i = startAt; i >= endAt; i--) { ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i]; if (curr == match0 || curr == match1) { return(i); } } break; case 3: Debug.Assert(anyOf != null); match0 = ignoreCase ? ASCIIChar.ToLower(anyOf[0]) : anyOf[0]; match1 = ignoreCase ? ASCIIChar.ToLower(anyOf[1]) : anyOf[1]; match2 = ignoreCase ? ASCIIChar.ToLower(anyOf[2]) : anyOf[2]; for (int i = startAt; i >= endAt; i--) { ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i]; if (curr == match0 || curr == match1 || curr == match2) { return(i); } } break; default: Debug.Assert(anyOf != null); ASCIIChar[] chars = ignoreCase ? anyOf.Select(ASCIIChar.ToLower).ToArray() : anyOf.ToArray(); for (int i = startAt; i >= endAt; i--) { ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i]; if (chars.Contains(curr)) { return(i); } } break; } return(-1); }
// TODO: Add startIndex and count methods? /// <summary> /// Determines whether the specified character appears within this string. /// </summary> /// <param name="value">The character to seek.</param> /// <param name="ignoreCase">True to ignore case; otherwise, false.</param> /// <returns></returns> public bool Contains(ASCIIChar value, bool ignoreCase = false) { return(IndexOf(value, ignoreCase) >= 0); }
/// <summary> /// Reports the zero-based index position of the last occurence of a specified character within this instance. /// </summary> /// <param name="value">The character to seek.</param> /// <param name="ignoreCase">True to ignore case; otherwise, false.</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> public int LastIndexOf(ASCIIChar value, bool ignoreCase = false) { return(LastIndexOf(value, 0, this.Length, ignoreCase)); }