public void General()
        {
            ConstantGrowArray <Range> a = new ConstantGrowArray <Range>(1, Range.Comparer)
            {
                new Range(1, 2), new Range(3, 6), new Range(2, 4)
            };

            Assert.Equal(3, a.Count);

            a.Sort();

            Assert.Equal(1, a[0].Start);
            Assert.Equal(2, a[1].Start);
            Assert.Equal(3, a[2].Start);

            Assert.True(a.Sorted);

            a.Add(new Range(4, 19));

            //Since we added a larger range, it should still be sorted.
            Assert.True(a.Sorted);

            a.Add(new Range(3, 20));

            Assert.False(a.Sorted);
        }
Пример #2
0
        public string?Build(string unit, long dataSize = -1)
        {
            //RFC7233: A server that supports range requests MAY ignore or reject a Range header field that consists of more than two overlapping ranges
            //RFC7233: A client that is requesting multiple ranges SHOULD list those ranges in ascending order

            //We do a couple of things here:
            //1. We merge ranges that overlap
            //2. We sort the ranges in ascending order to ease the work for the server
            //3. We shorten the range
            //4. We skip (and log) invalid ranges

            if (!HasData())
            {
                return(null);
            }

            //Reset state
            _invalidCount = 0;

            //We need an invalid index if we are going to report invalid ranges
            if (Options.Value.MergeOverlappingRanges || Options.Value.DiscardInvalidRanges)
            {
                _invalidIndex = new BitArray(_ranges !.Count);
            }

            if (_ranges !.Count > 1)
            {
                if (Options.Value.SortRanges || Options.Value.MergeOverlappingRanges)
                {
                    _ranges.Sort();
                }

                if (Options.Value.MergeOverlappingRanges)
                {
                    int       pointer  = 0;
                    ref Range previous = ref _ranges[pointer];

                    for (int i = 1; i < _ranges.Count; i++)
                    {
                        Range current = _ranges[i];

                        if (current.Start <= previous.End)
                        {
                            previous.End = Math.Max(previous.End, current.End);
                            ReportInvalid(i);
                        }
                        else
                        {
                            pointer++;
                        }
                    }
                }
            }