private List <DownloadRange> DetermineToDoRanges(long fileSize, List <DownloadRange> alreadyDoneRanges) { var result = new List <DownloadRange>(); var initialRange = new DownloadRange(0, fileSize); result.Add(initialRange); if (alreadyDoneRanges != null && alreadyDoneRanges.Count > 0) { foreach (var range in alreadyDoneRanges) { var newResult = new List <DownloadRange>(result); foreach (var resultRange in result) { if (this.downloadRangeHelper.RangesCollide(range, resultRange)) { newResult.Remove(resultRange); var difference = this.downloadRangeHelper.RangeDifference(resultRange, range); newResult.AddRange(difference); } } result = newResult; } } return(result); }
public List <DownloadRange> RangeDifference(DownloadRange fullRange, DownloadRange range) { var result = new List <DownloadRange>(); // no intersection if (!RangesCollide(fullRange, range)) { result.Add(fullRange); return(result); } // fullRange is part of range --> difference is empty if (fullRange.Start >= range.Start && fullRange.End <= range.End) { return(result); } if (fullRange.Start < range.Start) { result.Add(new DownloadRange(fullRange.Start, range.Start - fullRange.Start)); } if (fullRange.End > range.End) { result.Add(new DownloadRange(range.End + 1, fullRange.End - range.End)); } return(result); }
public bool Equals(DownloadRange r) { if ((Object)r == null) { return(false); } return((this.Start == r.Start) && (this.Length == r.Length)); }
public override bool Equals(Object obj) { if (obj == null) { return(false); } DownloadRange r = obj as DownloadRange; return(Equals(r)); }
private void StartDownload(DownloadRange range) { var download = this.downloadBuilder.Build(this.url, this.bufferSize, range.Start, range.Length); download.DataReceived += downloadDataReceived; download.DownloadCancelled += downloadCancelled; download.DownloadCompleted += downloadCompleted; download.Start(); lock (this.monitor) { this.downloads.Add(download, range); } }
private void downloadDataReceived(DownloadDataReceivedEventArgs args) { var offset = args.Offset; var count = args.Count; var data = args.Data; lock (this.monitor) { var justDownloadedRange = new DownloadRange(offset, count); var todoRange = this.ToDoRanges.Single(r => downloadRangeHelper.RangesCollide(r, justDownloadedRange)); this.ToDoRanges.Remove(todoRange); var differences = downloadRangeHelper.RangeDifference(todoRange, justDownloadedRange); this.ToDoRanges.AddRange(differences); var alreadyDoneRange = this.AlreadyDownloadedRanges.FirstOrDefault(r => r.End + 1 == justDownloadedRange.Start); if (alreadyDoneRange == null) { alreadyDoneRange = justDownloadedRange; this.AlreadyDownloadedRanges.Add(alreadyDoneRange); } else { alreadyDoneRange.Length += justDownloadedRange.Length; } var neighborRange = this.AlreadyDownloadedRanges.FirstOrDefault(r => r.Start == alreadyDoneRange.End + 1); if (neighborRange != null) { this.AlreadyDownloadedRanges.Remove(alreadyDoneRange); this.AlreadyDownloadedRanges.Remove(neighborRange); var combinedRange = new DownloadRange(alreadyDoneRange.Start, alreadyDoneRange.Length + neighborRange.Length); this.AlreadyDownloadedRanges.Add(combinedRange); } } this.OnDataReceived(new DownloadDataReceivedEventArgs(this, data, offset, count)); }
private void StartDownloadOfNextRange() { DownloadRange nextRange = null; lock (this.monitor) { nextRange = this.ToDoRanges.FirstOrDefault(r => !this.downloads.Values.Any(r2 => downloadRangeHelper.RangesCollide(r, r2))); } if (nextRange != null) { StartDownload(nextRange); } if (!this.downloads.Any()) { lock (this.monitor) { this.state = DownloadState.Finished; } this.OnDownloadCompleted(new DownloadEventArgs(this)); } }
public bool RangesCollide(DownloadRange range1, DownloadRange range2) { return(range1.Start <= range2.End && range2.Start <= range1.End); }