< Summary

Line coverage
43%
Covered lines: 42
Uncovered lines: 54
Coverable lines: 96
Total lines: 170
Line coverage: 43.7%
Branch coverage
41%
Covered branches: 10
Total branches: 24
Branch coverage: 41.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%110%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%110%
ToString()100%22100%
Equals(...)0%440%
GetHashCode()0%220%
Parse(...)0%220%
TryParse(...)0%440%
GetProductInfoLength(...)80%101092.59%
System.ICloneable.Clone()100%110%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics;
 5using System.Diagnostics.CodeAnalysis;
 6
 7namespace System.Net.Http.Headers
 8{
 9    public class ProductInfoHeaderValue : ICloneable
 10    {
 11        private readonly ProductHeaderValue? _product;
 12        private readonly string? _comment;
 13
 014        public ProductHeaderValue? Product => _product;
 15
 016        public string? Comment => _comment;
 17
 18        public ProductInfoHeaderValue(string productName, string? productVersion)
 019            : this(new ProductHeaderValue(productName, productVersion))
 020        {
 021        }
 22
 1646323        public ProductInfoHeaderValue(ProductHeaderValue product)
 1646324        {
 1646325            ArgumentNullException.ThrowIfNull(product);
 26
 1646327            _product = product;
 1646328        }
 29
 22330        public ProductInfoHeaderValue(string comment)
 22331        {
 22332            HeaderUtilities.CheckValidComment(comment);
 22333            _comment = comment;
 22334        }
 35
 036        private ProductInfoHeaderValue(ProductInfoHeaderValue source)
 037        {
 038            Debug.Assert(source != null);
 39
 040            _product = source._product;
 041            _comment = source._comment;
 042        }
 43
 44        public override string ToString()
 1347045        {
 1347046            if (_product == null)
 23547            {
 23548                Debug.Assert(_comment != null);
 23549                return _comment;
 50            }
 1323551            return _product.ToString();
 1347052        }
 53
 54        public override bool Equals([NotNullWhen(true)] object? obj)
 055        {
 056            ProductInfoHeaderValue? other = obj as ProductInfoHeaderValue;
 57
 058            if (other == null)
 059            {
 060                return false;
 61            }
 62
 063            if (_product == null)
 064            {
 65                // We compare comments using case-sensitive comparison.
 066                return string.Equals(_comment, other._comment, StringComparison.Ordinal);
 67            }
 68
 069            return _product.Equals(other._product);
 070        }
 71
 72        public override int GetHashCode()
 073        {
 074            if (_product == null)
 075            {
 076                Debug.Assert(_comment != null);
 077                return _comment.GetHashCode();
 78            }
 079            return _product.GetHashCode();
 080        }
 81
 82        public static ProductInfoHeaderValue Parse(string input)
 083        {
 084            int index = 0;
 085            object result = ProductInfoHeaderParser.SingleValueParser.ParseValue(
 086                input, null, ref index);
 087            if (index < input.Length)
 088            {
 89                // There is some invalid leftover data. Normally BaseHeaderParser.TryParseValue would
 90                // handle this, but ProductInfoHeaderValue does not derive from BaseHeaderParser.
 091                throw new FormatException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_heade
 92            }
 093            return (ProductInfoHeaderValue)result;
 094        }
 95
 96        public static bool TryParse([NotNullWhen(true)] string input, [NotNullWhen(true)] out ProductInfoHeaderValue? pa
 097        {
 098            int index = 0;
 099            parsedValue = null;
 100
 0101            if (ProductInfoHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out object? output))
 0102            {
 0103                if (index < input.Length)
 0104                {
 105                    // There is some invalid leftover data. Normally BaseHeaderParser.TryParseValue would
 106                    // handle this, but ProductInfoHeaderValue does not derive from BaseHeaderParser.
 0107                    return false;
 108                }
 0109                parsedValue = (ProductInfoHeaderValue)output;
 0110                return true;
 111            }
 0112            return false;
 0113        }
 114
 115        internal static int GetProductInfoLength(string? input, int startIndex, out ProductInfoHeaderValue? parsedValue)
 17142116        {
 17142117            Debug.Assert(startIndex >= 0);
 118
 17142119            parsedValue = null;
 120
 17142121            if (string.IsNullOrEmpty(input) || (startIndex >= input.Length))
 0122            {
 0123                return 0;
 124            }
 125
 17142126            int current = startIndex;
 127
 128            // Caller must remove leading whitespace.
 129            string? comment;
 130            ProductHeaderValue? product;
 17142131            if (input[current] == '(')
 555132            {
 133                int commentLength;
 555134                if (HttpRuleParser.GetCommentLength(input, current, out commentLength) != HttpParseResult.Parsed)
 332135                {
 332136                    return 0;
 137                }
 138
 223139                comment = input.Substring(current, commentLength);
 140
 223141                current += commentLength;
 223142                current += HttpRuleParser.GetWhitespaceLength(input, current);
 143
 223144                parsedValue = new ProductInfoHeaderValue(comment);
 223145            }
 146            else
 16587147            {
 148                // Trailing whitespace is removed by GetProductLength().
 16587149                int productLength = ProductHeaderValue.GetProductLength(input, current, out product);
 150
 16587151                if (productLength == 0)
 124152                {
 124153                    return 0;
 154                }
 155
 16463156                current += productLength;
 157
 16463158                parsedValue = new ProductInfoHeaderValue(product!);
 16463159            }
 160
 16686161            return current - startIndex;
 17142162        }
 163
 164        object ICloneable.Clone()
 0165        {
 0166            return new ProductInfoHeaderValue(this);
 0167        }
 168    }
 169}
 170