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); }
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++; } } } }