< Summary

Information
Class: System.Net.Http.Headers.ProductHeaderValue
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\ProductHeaderValue.cs
Line coverage
52%
Covered lines: 46
Uncovered lines: 42
Coverable lines: 88
Total lines: 158
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)

D:\runner\runtime\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)
 4881526            : this(name, null)
 4881527        {
 4881528        }
 29
 5139130        public ProductHeaderValue(string name, string? version)
 5139131        {
 5139132            HeaderUtilities.CheckValidToken(name);
 33
 5139134            if (!string.IsNullOrEmpty(version))
 257635            {
 257636                HeaderUtilities.CheckValidToken(version);
 257637                _version = version;
 257638            }
 39
 5139140            _name = name;
 5139141        }
 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()
 7931552        {
 7931553            if (string.IsNullOrEmpty(_version))
 7552554            {
 7552555                return _name;
 56            }
 379057            return _name + "/" + _version;
 7931558        }
 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)
 51711105        {
 51711106            Debug.Assert(startIndex >= 0);
 107
 51711108            parsedValue = null;
 109
 51711110            if (string.IsNullOrEmpty(input) || (startIndex >= input.Length))
 0111            {
 0112                return 0;
 113            }
 114
 115            // Parse the name string: <name> in '<name>/<version>'.
 51711116            int nameLength = HttpRuleParser.GetTokenLength(input, startIndex);
 117
 51711118            if (nameLength == 0)
 294119            {
 294120                return 0;
 121            }
 122
 51417123            string name = input.Substring(startIndex, nameLength);
 51417124            int current = startIndex + nameLength;
 51417125            current += HttpRuleParser.GetWhitespaceLength(input, current);
 126
 51417127            if ((current == input.Length) || (input[current] != '/'))
 48815128            {
 48815129                parsedValue = new ProductHeaderValue(name);
 48815130                return current - startIndex;
 131            }
 132
 2602133            current++; // Skip '/' delimiter.
 2602134            current += HttpRuleParser.GetWhitespaceLength(input, current);
 135
 136            // Parse the name string: <version> in '<name>/<version>'.
 2602137            int versionLength = HttpRuleParser.GetTokenLength(input, current);
 138
 2602139            if (versionLength == 0)
 26140            {
 26141                return 0; // If there is a '/' separator it must be followed by a valid token.
 142            }
 143
 2576144            string version = input.Substring(current, versionLength);
 145
 2576146            current += versionLength;
 2576147            current += HttpRuleParser.GetWhitespaceLength(input, current);
 148
 2576149            parsedValue = new ProductHeaderValue(name, version);
 2576150            return current - startIndex;
 51711151        }
 152
 153        object ICloneable.Clone()
 0154        {
 0155            return new ProductHeaderValue(this);
 0156        }
 157    }
 158}