< Summary

Information
Class: System.Net.Http.Headers.RetryConditionHeaderValue
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\RetryConditionHeaderValue.cs
Line coverage
50%
Covered lines: 42
Uncovered lines: 41
Coverable lines: 83
Total lines: 151
Line coverage: 50.6%
Branch coverage
46%
Covered branches: 14
Total branches: 30
Branch coverage: 46.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%110%
ToString()50%22100%
Equals(...)0%440%
GetHashCode()100%110%
Parse(...)100%110%
TryParse(...)0%220%
GetRetryConditionLength(...)72.22%181882.92%
System.ICloneable.Clone()100%110%

File(s)

D:\runner\runtime\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
 228        public RetryConditionHeaderValue(TimeSpan delta)
 229        {
 30            // The amount of seconds for 'delta' must be in the range 0..2^31
 231            ArgumentOutOfRangeException.ThrowIfGreaterThan(delta.TotalSeconds, int.MaxValue);
 32
 233            _delta = delta;
 234        }
 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() =>
 345            _delta.Ticks != DeltaNotSetTicksSentinel
 346                ? ((int)_delta.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo)
 347                : _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)
 3278        {
 3279            Debug.Assert(startIndex >= 0);
 80
 3281            parsedValue = null;
 82
 3283            if (string.IsNullOrEmpty(input) || (startIndex >= input.Length))
 084            {
 085                return 0;
 86            }
 87
 3288            int current = startIndex;
 89
 90            // Caller must remove leading whitespace.
 3291            DateTimeOffset date = DateTimeOffset.MinValue;
 3292            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.
 3296            char firstChar = input[current];
 97
 3298            if (char.IsAsciiDigit(firstChar))
 3099            {
 30100                int deltaStartIndex = current;
 30101                int deltaLength = HttpRuleParser.GetNumberLength(input, current, false);
 102
 103                // The value must be in the range 0..2^31
 30104                if ((deltaLength == 0) || (deltaLength > HttpRuleParser.MaxInt32Digits))
 18105                {
 18106                    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)
 6114                {
 6115                    return 0;
 116                }
 117
 6118                if (!HeaderUtilities.TryParseInt32(input, deltaStartIndex, deltaLength, out deltaSeconds))
 4119                {
 4120                    return 0; // int.TryParse() may return 'false' if the value has 10 digits and is > Int32.MaxValue.
 121                }
 2122            }
 123            else
 2124            {
 2125                if (!HttpDateParser.TryParse(input.AsSpan(current), out date))
 2126                {
 2127                    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
 2134            if (deltaSeconds == -1) // we didn't change delta, so we must have found a date.
 0135            {
 0136                parsedValue = new RetryConditionHeaderValue(date);
 0137            }
 138            else
 2139            {
 2140                parsedValue = new RetryConditionHeaderValue(new TimeSpan(0, 0, deltaSeconds));
 2141            }
 142
 2143            return current - startIndex;
 32144        }
 145
 146        object ICloneable.Clone()
 0147        {
 0148            return new RetryConditionHeaderValue(this);
 0149        }
 150    }
 151}