< Summary

Line coverage
45%
Covered lines: 38
Uncovered lines: 45
Coverable lines: 83
Total lines: 152
Line coverage: 45.7%
Branch coverage
40%
Covered branches: 12
Total branches: 30
Branch coverage: 40%
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%110%
ToString()50%22100%
Equals(...)0%440%
GetHashCode()100%110%
Parse(...)100%110%
TryParse(...)0%220%
GetRetryConditionLength(...)61.11%181873.17%
System.ICloneable.Clone()100%110%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.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;
 6using System.Globalization;
 7
 8namespace System.Net.Http.Headers
 9{
 10    public class RetryConditionHeaderValue : ICloneable
 11    {
 12        private const long DeltaNotSetTicksSentinel = long.MaxValue;
 13
 14        // Only one of date and delta may be set.
 15        private readonly DateTimeOffset _date;
 16        private readonly TimeSpan _delta;
 17
 018        public DateTimeOffset? Date => _delta.Ticks == DeltaNotSetTicksSentinel ? _date : null;
 19
 020        public TimeSpan? Delta => _delta.Ticks == DeltaNotSetTicksSentinel ? null : _delta;
 21
 022        public RetryConditionHeaderValue(DateTimeOffset date)
 023        {
 024            _date = date;
 025            _delta = new TimeSpan(DeltaNotSetTicksSentinel);
 026        }
 27
 428        public RetryConditionHeaderValue(TimeSpan delta)
 429        {
 30            // The amount of seconds for 'delta' must be in the range 0..2^31
 431            ArgumentOutOfRangeException.ThrowIfGreaterThan(delta.TotalSeconds, int.MaxValue);
 32
 433            _delta = delta;
 434        }
 35
 036        private RetryConditionHeaderValue(RetryConditionHeaderValue source)
 037        {
 038            Debug.Assert(source != null);
 39
 040            _delta = source._delta;
 041            _date = source._date;
 042        }
 43
 44        public override string ToString() =>
 645            _delta.Ticks != DeltaNotSetTicksSentinel
 646                ? ((int)_delta.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo)
 647                : _date.ToString("r");
 48
 49        public override bool Equals([NotNullWhen(true)] object? obj) =>
 050            obj is RetryConditionHeaderValue other &&
 051            _delta == other._delta &&
 052            _date == other._date;
 53
 54        public override int GetHashCode() =>
 055            HashCode.Combine(_delta, _date);
 56
 57        public static RetryConditionHeaderValue Parse(string input)
 058        {
 059            int index = 0;
 060            return (RetryConditionHeaderValue)GenericHeaderParser.RetryConditionParser.ParseValue(
 061                input, null, ref index);
 062        }
 63
 64        public static bool TryParse([NotNullWhen(true)] string? input, [NotNullWhen(true)] out RetryConditionHeaderValue
 065        {
 066            int index = 0;
 067            parsedValue = null;
 68
 069            if (GenericHeaderParser.RetryConditionParser.TryParseValue(input, null, ref index, out object? output))
 070            {
 071                parsedValue = (RetryConditionHeaderValue)output!;
 072                return true;
 73            }
 074            return false;
 075        }
 76
 77        internal static int GetRetryConditionLength(string? input, int startIndex, out object? parsedValue)
 1878        {
 1879            Debug.Assert(startIndex >= 0);
 80
 1881            parsedValue = null;
 82
 1883            if (string.IsNullOrEmpty(input) || (startIndex >= input.Length))
 084            {
 085                return 0;
 86            }
 87
 1888            int current = startIndex;
 89
 90            // Caller must remove leading whitespace.
 1891            DateTimeOffset date = DateTimeOffset.MinValue;
 1892            int deltaSeconds = -1; // use -1 to indicate that the value was not set. 'delta' values are always >=0
 93
 94            // We either have a timespan or a date/time value. Determine which one we have by looking at the first char.
 95            // If it is a number, we have a timespan, otherwise we assume we have a date.
 1896            char firstChar = input[current];
 97
 1898            if (char.IsAsciiDigit(firstChar))
 1299            {
 12100                int deltaStartIndex = current;
 12101                int deltaLength = HttpRuleParser.GetNumberLength(input, current, false);
 102
 103                // The value must be in the range 0..2^31
 12104                if ((deltaLength == 0) || (deltaLength > HttpRuleParser.MaxInt32Digits))
 0105                {
 0106                    return 0;
 107                }
 108
 12109                current += deltaLength;
 12110                current += HttpRuleParser.GetWhitespaceLength(input, current);
 111
 112                // RetryConditionHeaderValue only allows 1 value. There must be no delimiter/other chars after 'delta'
 12113                if (current != input.Length)
 8114                {
 8115                    return 0;
 116                }
 117
 4118                if (!HeaderUtilities.TryParseInt32(input, deltaStartIndex, deltaLength, out deltaSeconds))
 0119                {
 0120                    return 0; // int.TryParse() may return 'false' if the value has 10 digits and is > Int32.MaxValue.
 121                }
 4122            }
 123            else
 6124            {
 6125                if (!HttpDateParser.TryParse(input.AsSpan(current), out date))
 6126                {
 6127                    return 0;
 128                }
 129
 130                // If we got a valid date, then the parser consumed the whole string (incl. trailing whitespace).
 0131                current = input.Length;
 0132            }
 133
 4134            if (deltaSeconds == -1) // we didn't change delta, so we must have found a date.
 0135            {
 0136                parsedValue = new RetryConditionHeaderValue(date);
 0137            }
 138            else
 4139            {
 4140                parsedValue = new RetryConditionHeaderValue(new TimeSpan(0, 0, deltaSeconds));
 4141            }
 142
 4143            return current - startIndex;
 18144        }
 145
 146        object ICloneable.Clone()
 0147        {
 0148            return new RetryConditionHeaderValue(this);
 0149        }
 150    }
 151}
 152