// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.Diagnostics; using System.Net.Http.Headers; namespace System.Net.Http.Formatting { /// /// Implementation of that can compare content negotiation header fields /// based on their quality values (a.k.a q-values). This applies to values used in accept-charset, /// accept-encoding, accept-language and related header fields with similar syntax rules. See /// for a comparer for media type /// q-values. /// internal class StringWithQualityHeaderValueComparer : IComparer { private static readonly StringWithQualityHeaderValueComparer _qualityComparer = new StringWithQualityHeaderValueComparer(); private StringWithQualityHeaderValueComparer() { } public static StringWithQualityHeaderValueComparer QualityComparer { get { return _qualityComparer; } } /// /// Compares two based on their quality value (a.k.a their /// "q-value"). Values with identical q-values are considered equal (i.e the result is 0) with the exception of /// wild-card values (i.e. a value of "*") which are considered less than non-wild-card values. This allows to /// sort a sequence of following their q-values ending up with any /// wild-cards at the end. /// /// The first value to compare. /// The second value to compare /// The result of the comparison. public int Compare( StringWithQualityHeaderValue stringWithQuality1, StringWithQualityHeaderValue stringWithQuality2) { Debug.Assert(stringWithQuality1 != null); Debug.Assert(stringWithQuality2 != null); var quality1 = stringWithQuality1.Quality ?? FormattingUtilities.Match; var quality2 = stringWithQuality2.Quality ?? FormattingUtilities.Match; var qualityDifference = quality1 - quality2; if (qualityDifference < 0) { return -1; } else if (qualityDifference > 0) { return 1; } if (!string.Equals(stringWithQuality1.Value, stringWithQuality2.Value, StringComparison.OrdinalIgnoreCase)) { if (string.Equals(stringWithQuality1.Value, "*", StringComparison.Ordinal)) { return -1; } else if (string.Equals(stringWithQuality2.Value, "*", StringComparison.Ordinal)) { return 1; } } return 0; } } }