Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
StringComparer Create(culture, CompareOptions) overload (#16334)
Browse files Browse the repository at this point in the history
* String Create options overlaod

* Minor Change

* Feedback

* validation on options

* obsolete removed

* Implementing Iserializable and removing ignorecase

* HashCode and serialization changes

* made inline

* Space Corrected

Signed-off-by: dotnet-bot-corefx-mirror <[email protected]>
  • Loading branch information
Anipik authored and stephentoub committed Feb 15, 2018
1 parent c8d23b4 commit f0e6d50
Showing 1 changed file with 50 additions and 17 deletions.
67 changes: 50 additions & 17 deletions src/Common/src/CoreLib/System/StringComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace System
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public abstract class StringComparer : IComparer, IEqualityComparer, IComparer<string>, IEqualityComparer<string>
{
private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, false);
private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, true);
private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, CompareOptions.None);
private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
private static readonly OrdinalCaseSensitiveComparer s_ordinal = new OrdinalCaseSensitiveComparer();
private static readonly OrdinalIgnoreCaseComparer s_ordinalIgnoreCase = new OrdinalIgnoreCaseComparer();

Expand All @@ -38,15 +38,15 @@ public static StringComparer CurrentCulture
{
get
{
return new CultureAwareComparer(CultureInfo.CurrentCulture, false);
return new CultureAwareComparer(CultureInfo.CurrentCulture, CompareOptions.None);
}
}

public static StringComparer CurrentCultureIgnoreCase
{
get
{
return new CultureAwareComparer(CultureInfo.CurrentCulture, true);
return new CultureAwareComparer(CultureInfo.CurrentCulture, CompareOptions.IgnoreCase);
}
}

Expand Down Expand Up @@ -94,8 +94,18 @@ public static StringComparer Create(CultureInfo culture, bool ignoreCase)
{
throw new ArgumentNullException(nameof(culture));
}

return new CultureAwareComparer(culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
}

public static StringComparer Create(CultureInfo culture, CompareOptions options)
{
if (culture == null)
{
throw new ArgumentException(nameof(culture));
}

return new CultureAwareComparer(culture, ignoreCase);
return new CultureAwareComparer(culture, options);
}

public int Compare(object x, object y)
Expand Down Expand Up @@ -123,7 +133,6 @@ public int Compare(object x, object y)
throw new ArgumentException(SR.Argument_ImplementIComparable);
}


public new bool Equals(Object x, Object y)
{
if (x == y) return true;
Expand Down Expand Up @@ -163,32 +172,50 @@ public int GetHashCode(object obj)

[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public sealed class CultureAwareComparer : StringComparer
public sealed class CultureAwareComparer : StringComparer, ISerializable
{
private const CompareOptions ValidCompareMaskOffFlags = ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);

private readonly CompareInfo _compareInfo; // Do not rename (binary serialization)
private readonly bool _ignoreCase; // Do not rename (binary serialization)
private CompareOptions _options;

internal CultureAwareComparer(CultureInfo culture, bool ignoreCase)
internal CultureAwareComparer(CultureInfo culture, CompareOptions compareOptions)
{
_compareInfo = culture.CompareInfo;
_ignoreCase = ignoreCase;

if ((compareOptions & CultureAwareComparer.ValidCompareMaskOffFlags) != 0)
{
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(compareOptions));
}
_options = compareOptions;
}

private CompareOptions Options => _ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None;
private CultureAwareComparer(SerializationInfo info, StreamingContext context)
{
_compareInfo = (CompareInfo)info.GetValue("_compareInfo", typeof(CompareInfo));
bool ignoreCase = info.GetBoolean("_ignoreCase");

var obj = info.GetValueNoThrow("_options", typeof(CompareOptions));
if (obj != null)
_options = (CompareOptions)obj;

// fix up the _options value in case we are getting old serialized object not having _options
_options |= ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None;
}

public override int Compare(string x, string y)
{
if (object.ReferenceEquals(x, y)) return 0;
if (x == null) return -1;
if (y == null) return 1;
return _compareInfo.Compare(x, y, Options);
return _compareInfo.Compare(x, y, _options);
}

public override bool Equals(string x, string y)
{
if (object.ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return _compareInfo.Compare(x, y, Options) == 0;
return _compareInfo.Compare(x, y, _options) == 0;
}

public override int GetHashCode(string obj)
Expand All @@ -197,7 +224,7 @@ public override int GetHashCode(string obj)
{
throw new ArgumentNullException(nameof(obj));
}
return _compareInfo.GetHashCodeOfString(obj, Options);
return _compareInfo.GetHashCodeOfString(obj, _options);
}

// Equals method for the comparer itself.
Expand All @@ -206,14 +233,20 @@ public override bool Equals(object obj)
CultureAwareComparer comparer = obj as CultureAwareComparer;
return
comparer != null &&
_ignoreCase == comparer._ignoreCase &&
_options == comparer._options &&
_compareInfo.Equals(comparer._compareInfo);
}

public override int GetHashCode()
{
int hashCode = _compareInfo.GetHashCode();
return _ignoreCase ? ~hashCode : hashCode;
return _compareInfo.GetHashCode() ^ ((int)_options & 0x7FFFFFFF);
}

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("_compareInfo", _compareInfo);
info.AddValue("_options", _options);
info.AddValue("_ignoreCase", (_options & CompareOptions.IgnoreCase) != 0);
}
}

Expand Down

0 comments on commit f0e6d50

Please sign in to comment.