platform/common/range_header/lib/src/range_header_item.dart

94 lines
2.4 KiB
Dart
Raw Normal View History

import 'dart:math';
import 'package:quiver/core.dart';
/// Represents an individual range, with an optional start index and optional end index.
class RangeHeaderItem implements Comparable<RangeHeaderItem> {
/// The index at which this chunk begins. May be `-1`.
final int start;
/// The index at which this chunk ends. May be `-1`.
final int end;
const RangeHeaderItem([this.start = -1, this.end = -1]);
/// Joins two items together into the largest possible range.
RangeHeaderItem consolidate(RangeHeaderItem other) {
if (!(other.overlaps(this))) {
throw ArgumentError('The two ranges do not overlap.');
}
return RangeHeaderItem(min(start, other.start), max(end, other.end));
}
@override
int get hashCode => hash2(start, end);
@override
bool operator ==(other) =>
other is RangeHeaderItem && other.start == start && other.end == end;
bool overlaps(RangeHeaderItem other) {
if (other.start <= start) {
return other.end < start;
} else if (other.start > start) {
return other.start <= end;
}
return false;
}
@override
int compareTo(RangeHeaderItem other) {
if (other.start > start) {
return -1;
} else if (other.start == start) {
if (other.end == end) {
return 0;
} else if (other.end < end) {
return 1;
} else {
return -1;
}
} else if (other.start < start) {
return 1;
} else {
return -1;
}
}
@override
String toString() {
if (start > -1 && end > -1) {
return '$start-$end';
} else if (start > -1) {
return '$start-';
} else {
return '-$end';
}
}
/// Creates a representation of this instance suitable for a `Content-Range` header.
///
/// This can only be used if the user request only one range. If not, send a
/// `multipart/byteranges` response.
///
/// Please adhere to the standard!!!
/// http://httpwg.org/specs/rfc7233.html
String toContentRange([int? totalSize]) {
// var maxIndex = totalSize != null ? (totalSize - 1).toString() : '*';
var s = start > -1 ? start : 0;
if (end == -1) {
if (totalSize == null) {
throw UnsupportedError(
'If the end of this range is unknown, `totalSize` must not be null.');
} else {
// if (end == totalSize - 1) {
return '$s-${totalSize - 1}/$totalSize';
}
}
return '$s-$end/$totalSize';
}
}