Files
eh-downloader/server/range_parser.ts
2023-06-15 18:05:09 +08:00

67 lines
1.9 KiB
TypeScript

export type Range = {
start: number;
end: number;
};
export type Ranges = Range[] & { type: string };
export function parse_range(size: number, str: string, combine = false) {
const index = str.indexOf("=");
if (index === -1) {
return -2;
}
const arr = str.slice(index + 1).split(",");
/**@ts-ignore */
const ranges = [] as Ranges;
ranges.type = str.slice(0, index);
for (const r of arr) {
const range = r.split("-");
let start = parseInt(range[0], 10);
let end = parseInt(range[1], 10);
if (isNaN(start)) {
start = size - end;
end = size - 1;
} else if (isNaN(end)) {
end = size - 1;
}
if (end > size - 1) {
end = size - 1;
}
if (isNaN(start) || isNaN(end) || start > end || start < 0) {
continue;
}
ranges.push({
start: start,
end: end,
});
}
if (ranges.length < 1) return -1;
return combine ? combineRanges(ranges) : ranges;
}
function combineRanges(ranges: Ranges) {
const ordered = ranges.map((r, index) => {
return { start: r.start, end: r.end, index };
}).sort((a, b) => a.start - b.start);
let j = 0;
for (let i = 1; i < ordered.length; i++) {
const range = ordered[i];
const current = ordered[j];
if (range.start > current.end + 1) {
ordered[++j] = range;
} else if (range.end > current.end) {
current.end = range.end;
current.index = Math.min(current.index, range.index);
}
}
ordered.length = j + 1;
const combined: Range[] = ordered.sort((a, b) => a.index - b.index).map(
(d) => {
return { start: d.start, end: d.end };
},
);
/**@ts-ignore */
const r = combined as Ranges;
r.type = ranges.type;
return r;
}