< Summary

Information
Class: System.Net.Http.Headers.RangeConditionHeaderValue
Assembly: System.Net.Http
File(s): D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\RangeConditionHeaderValue.cs
Line coverage
48%
Covered lines: 38
Uncovered lines: 41
Coverable lines: 79
Total lines: 143
Line coverage: 48.1%
Branch coverage
52%
Covered branches: 19
Total branches: 36
Branch coverage: 52.7%
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%
.ctor(...)100%110%
ToString()50%44100%
Equals(...)0%660%
GetHashCode()0%220%
Parse(...)100%110%
TryParse(...)0%220%
GetRangeConditionLength(...)85%202086.48%
System.ICloneable.Clone()100%110%

File(s)

D:\runner\runtime\src\libraries\System.Net.Http\src\System\Net\Http\Headers\RangeConditionHeaderValue.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 RangeConditionHeaderValue : ICloneable
 10    {
 11        // Exactly one of date and entityTag will be set.
 12        private readonly DateTimeOffset _date;
 13        private readonly EntityTagHeaderValue? _entityTag;
 14
 015        public DateTimeOffset? Date => _entityTag is null ? _date : null;
 16
 017        public EntityTagHeaderValue? EntityTag => _entityTag;
 18
 019        public RangeConditionHeaderValue(DateTimeOffset date)
 020        {
 021            _date = date;
 022        }
 23
 8624        public RangeConditionHeaderValue(EntityTagHeaderValue entityTag)
 8625        {
 8626            ArgumentNullException.ThrowIfNull(entityTag);
 27
 8628            _entityTag = entityTag;
 8629        }
 30
 31        public RangeConditionHeaderValue(string entityTag)
 032            : this(new EntityTagHeaderValue(entityTag))
 033        {
 034        }
 35
 036        private RangeConditionHeaderValue(RangeConditionHeaderValue source)
 037        {
 038            Debug.Assert(source != null);
 39
 040            _entityTag = source._entityTag;
 041            _date = source._date;
 042        }
 43
 12944        public override string ToString() => _entityTag?.ToString() ?? _date.ToString("r");
 45
 46        public override bool Equals([NotNullWhen(true)] object? obj) =>
 047            obj is RangeConditionHeaderValue other &&
 048            (_entityTag is null ? other._entityTag is null : _entityTag.Equals(other._entityTag)) &&
 049            _date == other._date;
 50
 051        public override int GetHashCode() => _entityTag?.GetHashCode() ?? _date.GetHashCode();
 52
 53        public static RangeConditionHeaderValue Parse(string input)
 054        {
 055            int index = 0;
 056            return (RangeConditionHeaderValue)GenericHeaderParser.RangeConditionParser.ParseValue(
 057                input, null, ref index);
 058        }
 59
 60        public static bool TryParse([NotNullWhen(true)] string? input, [NotNullWhen(true)] out RangeConditionHeaderValue
 061        {
 062            int index = 0;
 063            parsedValue = null;
 64
 065            if (GenericHeaderParser.RangeConditionParser.TryParseValue(input, null, ref index, out object? output))
 066            {
 067                parsedValue = (RangeConditionHeaderValue)output!;
 068                return true;
 69            }
 070            return false;
 071        }
 72
 73        internal static int GetRangeConditionLength(string? input, int startIndex, out object? parsedValue)
 132874        {
 132875            Debug.Assert(startIndex >= 0);
 76
 132877            parsedValue = null;
 78
 79            // Make sure we have at least 2 characters
 132880            if (string.IsNullOrEmpty(input) || (startIndex + 1 >= input.Length))
 481            {
 482                return 0;
 83            }
 84
 132485            int current = startIndex;
 86
 87            // Caller must remove leading whitespace.
 132488            DateTimeOffset date = DateTimeOffset.MinValue;
 132489            EntityTagHeaderValue? entityTag = null;
 90
 91            // Entity tags are quoted strings optionally preceded by "W/". By looking at the first two character we
 92            // can determine whether the string is en entity tag or a date.
 132493            char firstChar = input[current];
 132494            char secondChar = input[current + 1];
 95
 132496            if ((firstChar == '\"') || (((firstChar == 'w') || (firstChar == 'W')) && (secondChar == '/')))
 130697            {
 98                // trailing whitespace is removed by GetEntityTagLength()
 130699                int entityTagLength = EntityTagHeaderValue.GetEntityTagLength(input, current, out entityTag);
 100
 1306101                if (entityTagLength == 0)
 1194102                {
 1194103                    return 0;
 104                }
 105
 112106                current += entityTagLength;
 107
 108                // RangeConditionHeaderValue only allows 1 value. There must be no delimiter/other chars after an
 109                // entity tag.
 112110                if (current != input.Length)
 26111                {
 26112                    return 0;
 113                }
 86114            }
 115            else
 18116            {
 18117                if (!HttpDateParser.TryParse(input.AsSpan(current), out date))
 18118                {
 18119                    return 0;
 120                }
 121
 122                // If we got a valid date, then the parser consumed the whole string (incl. trailing whitespace).
 0123                current = input.Length;
 0124            }
 125
 86126            if (entityTag == null)
 0127            {
 0128                parsedValue = new RangeConditionHeaderValue(date);
 0129            }
 130            else
 86131            {
 86132                parsedValue = new RangeConditionHeaderValue(entityTag);
 86133            }
 134
 86135            return current - startIndex;
 1328136        }
 137
 138        object ICloneable.Clone()
 0139        {
 0140            return new RangeConditionHeaderValue(this);
 0141        }
 142    }
 143}