/// <summary> /// Gets a hash code for this string, ignoring case. If strings A and B are such that A.Equals(B), then /// they will return the same hash code. /// </summary> public int GetHashCodeIgnoreCase() { // Adapted from https://referencesource.microsoft.com/#mscorlib/system/string.cs int hash1 = 5381; int hash2 = hash1; for (int i = 0; i < _segment1.Length; i++) { char c = SpanStringComparer.ToUpperAscii(_segment1.Span[i]); int lowByte = c & 0xFF; hash1 = ((hash1 << 5) + hash1) ^ lowByte; int highByte = (c & 0xFF00) >> 8; hash2 = ((hash2 << 5) + hash2) ^ highByte; } for (int i = 0; i < _segment2.Length; i++) { char c = SpanStringComparer.ToUpperAscii(_segment2.Span[i]); int lowByte = c & 0xFF; hash1 = ((hash1 << 5) + hash1) ^ lowByte; int highByte = (c & 0xFF00) >> 8; hash2 = ((hash2 << 5) + hash2) ^ highByte; } return(hash1 + (hash2 * 1566083941)); }
/// <summary> /// Compares two SpanStrings using an ordinal comparison. /// </summary> /// <param name="a">The first string to compare.</param> /// <param name="b">The second string to compare.</param> /// <returns>True if the strings are equal.</returns> public static bool EqualsIgnoreCase(SpanString1 a, SpanString2 b) { if (a.Length != b.Length) { return false; } var s1Enum = new Enumerator(a); var s2Enum = new SpanString2.Enumerator(b); for (int i = 0; i < a.Length; i++) { int c1 = SpanStringComparer.ToUpperAscii(s1Enum.Next()); int c2 = SpanStringComparer.ToUpperAscii(s2Enum.Next()); if (c1 != c2) { return false; } } return true; }
/// <summary> /// Compares this instance with a specified SpanString2 using a case insensitive /// ordinal comparison, and indicates whether this instance precedes, follows, or /// appears in the same position in the sort order as the specified string. /// </summary> /// <param name="other">The string to compare with this instance.</param> /// <returns>A 32-bit signed integer that indicates whether this instance precedes, follows, or appears in the same position in the sort order as the strB parameter.</returns> public int CompareToIgnoreCase(SpanString2 other) { int length = Math.Min(Length, other.Length); var s1Enum = new Enumerator(this); var s2Enum = new Enumerator(other); for (int i = 0; i < length; i++) { int c1 = SpanStringComparer.ToUpperAscii(s1Enum.Next()); int c2 = SpanStringComparer.ToUpperAscii(s2Enum.Next()); int cmp = c1.CompareTo(c2); if (cmp != 0) { return(cmp); } } // At this point, we have compared all the characters in at least one string. // The longer string will be larger. return(Length - other.Length); }
/// <summary> /// Compares this instance with a specified SpanString1 using an ordinal /// comparison and case-insensitivity, and indicates whether this /// instance precedes, follows, or appears in the same position /// in the sort order as the specified string. /// </summary> /// <param name="other">The string to compare with this instance.</param> /// <returns>A 32-bit signed integer that indicates whether this instance precedes, follows, or appears in the same position in the sort order as the strB parameter.</returns> public int CompareToIgnoreCase(SpanString1 other) { // Adapted from https://referencesource.microsoft.com/#mscorlib/system/string.cs CompareOrdinalHelper() int length = Math.Min(Length, other.Length); var s1Enum = new Enumerator(this); var s2Enum = new SpanString1.Enumerator(other); for (int i = 0; i < length; i++) { int c1 = SpanStringComparer.ToUpperAscii(s1Enum.Next()); int c2 = SpanStringComparer.ToUpperAscii(s2Enum.Next()); int cmp = c1.CompareTo(c2); if (cmp != 0) { return(cmp); } } // At this point, we have compared all the characters in at least one string. // The longer string will be larger. return(Length - other.Length); }