< Summary

Line coverage
52%
Covered lines: 46
Uncovered lines: 42
Coverable lines: 88
Total lines: 159
Line coverage: 52.2%
Branch coverage
58%
Covered branches: 14
Total branches: 24
Branch coverage: 58.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

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

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.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 ProductHeaderValue : ICloneable
 10    {
 11        private readonly string _name;
 12        private readonly string? _version;
 13
 14        public string Name
 15        {
 016            get { return _name; }
 17        }
 18
 19        // We can't use the System.Version type, since a version can be e.g. "x11".
 20        public string? Version
 21        {
 022            get { return _version; }
 23        }
 24
 25        public ProductHeaderValue(string name)
 1926726            : this(name, null)
 1926727        {
 1926728        }
 29
 1943930        public ProductHeaderValue(string name, string? version)
 1943931        {
 1943932            HeaderUtilities.CheckValidToken(name);
 33
 1943934            if (!string.IsNullOrEmpty(version))
 17235            {
 17236                HeaderUtilities.CheckValidToken(version);
 17237                _version = version;
 17238            }
 39
 1943940            _name = name;
 1943941        }
 42
 043        private ProductHeaderValue(ProductHeaderValue source)
 044        {
 045            Debug.Assert(source != null);
 46
 047            _name = source._name;
 048            _version = source._version;
 049        }
 50
 51        public override string ToString()
 1795552        {
 1795553            if (string.IsNullOrEmpty(_version))
 1790554            {
 1790555                return _name;
 56            }
 5057            return _name + "/" + _version;
 1795558        }
 59
 60        public override bool Equals([NotNullWhen(true)] object? obj)
 061        {
 062            ProductHeaderValue? other = obj as ProductHeaderValue;
 63
 064            if (other == null)
 065            {
 066                return false;
 67            }
 68
 069            return string.Equals(_name, other._name, StringComparison.OrdinalIgnoreCase) &&
 070                string.Equals(_version, other._version, StringComparison.OrdinalIgnoreCase);
 071        }
 72
 73        public override int GetHashCode()
 074        {
 075            int result = StringComparer.OrdinalIgnoreCase.GetHashCode(_name);
 76
 077            if (!string.IsNullOrEmpty(_version))
 078            {
 079                result ^= StringComparer.OrdinalIgnoreCase.GetHashCode(_version);
 080            }
 81
 082            return result;
 083        }
 84
 85        public static ProductHeaderValue Parse(string input)
 086        {
 087            int index = 0;
 088            return (ProductHeaderValue)GenericHeaderParser.SingleValueProductParser.ParseValue(input, null, ref index);
 089        }
 90
 91        public static bool TryParse([NotNullWhen(true)] string? input, [NotNullWhen(true)] out ProductHeaderValue? parse
 092        {
 093            int index = 0;
 094            parsedValue = null;
 95
 096            if (GenericHeaderParser.SingleValueProductParser.TryParseValue(input, null, ref index, out object? output))
 097            {
 098                parsedValue = (ProductHeaderValue)output!;
 099                return true;
 100            }
 0101            return false;
 0102        }
 103
 104        internal static int GetProductLength(string input, int startIndex, out ProductHeaderValue? parsedValue)
 19639105        {
 19639106            Debug.Assert(startIndex >= 0);
 107
 19639108            parsedValue = null;
 109
 19639110            if (string.IsNullOrEmpty(input) || (startIndex >= input.Length))
 0111            {
 0112                return 0;
 113            }
 114
 115            // Parse the name string: <name> in '<name>/<version>'.
 19639116            int nameLength = HttpRuleParser.GetTokenLength(input, startIndex);
 117
 19639118            if (nameLength == 0)
 162119            {
 162120                return 0;
 121            }
 122
 19477123            string name = input.Substring(startIndex, nameLength);
 19477124            int current = startIndex + nameLength;
 19477125            current += HttpRuleParser.GetWhitespaceLength(input, current);
 126
 19477127            if ((current == input.Length) || (input[current] != '/'))
 19267128            {
 19267129                parsedValue = new ProductHeaderValue(name);
 19267130                return current - startIndex;
 131            }
 132
 210133            current++; // Skip '/' delimiter.
 210134            current += HttpRuleParser.GetWhitespaceLength(input, current);
 135
 136            // Parse the name string: <version> in '<name>/<version>'.
 210137            int versionLength = HttpRuleParser.GetTokenLength(input, current);
 138
 210139            if (versionLength == 0)
 38140            {
 38141                return 0; // If there is a '/' separator it must be followed by a valid token.
 142            }
 143
 172144            string version = input.Substring(current, versionLength);
 145
 172146            current += versionLength;
 172147            current += HttpRuleParser.GetWhitespaceLength(input, current);
 148
 172149            parsedValue = new ProductHeaderValue(name, version);
 172150            return current - startIndex;
 19639151        }
 152
 153        object ICloneable.Clone()
 0154        {
 0155            return new ProductHeaderValue(this);
 0156        }
 157    }
 158}
 159