Files
PDFPatcher/App/Model/PageRangeCollection.cs
2025-06-24 20:38:09 +08:00

135 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using CLR;
using PDFPatcher.Common;
namespace PDFPatcher.Model
{
internal sealed class PageRangeCollection : List<PageRange>
{
private PageRangeCollection() { }
public int TotalPages {
get {
int c = 0;
foreach (var item in this) {
c += item.Count;
}
return c;
}
}
public bool IsInRange(int value) {
foreach (var item in this) {
if (item.StartValue < item.EndValue && value.IsBetween(item.StartValue, item.EndValue)
|| value.IsBetween(item.EndValue, item.StartValue)) {
return true;
}
}
return false;
}
internal void Collapse(int minValue, int maxValue) {
if (maxValue < minValue) {
throw new ArgumentException("maxValue must greater than minValue");
}
for (int i = Count - 1; i >= 0; i--) {
var r = this[i];
SetReverseNumber(ref r.StartValue, maxValue);
SetReverseNumber(ref r.EndValue, maxValue);
if (r.StartValue < r.EndValue) {
if (r.EndValue < minValue || maxValue < r.StartValue) {
RemoveAt(i);
continue;
}
if (minValue <= r.StartValue && r.EndValue <= maxValue) {
continue;
}
if (r.StartValue < minValue) {
r.StartValue = minValue;
}
if (r.EndValue > maxValue) {
r.EndValue = maxValue;
}
}
else /*if (r.StartValue >= r.EndValue)*/ {
if (r.StartValue < minValue || maxValue < r.EndValue) {
RemoveAt(i);
continue;
}
if (maxValue >= r.StartValue && r.EndValue >= minValue) {
continue;
}
if (r.EndValue < minValue) {
r.EndValue = minValue;
}
if (r.StartValue > maxValue) {
r.StartValue = maxValue;
}
}
this[i] = r;
}
}
internal static PageRangeCollection CreateSingle(int minValue, int maxValue) {
var r = new PageRangeCollection {
new PageRange(minValue, maxValue)
};
return r;
}
internal static PageRangeCollection Parse(string rangeText, int minValue, int maxValue, bool addDefaultRange) {
var r = new PageRangeCollection();
if (!String.IsNullOrEmpty(rangeText)) {
var ranges = rangeText.Split(',', ';', ' ', '\t');
string startRange, endRange;
int startNum, endNum;
foreach (string range in ranges) {
if (range.Length == 0) {
continue;
}
startNum = endNum = 0;
int rangeIndicator = range.Length > 1 ? range.IndexOf('-', 1) /*排除首位可能是负数页码的可能*/ : -1;
if (rangeIndicator > 0) {
startRange = range.Substring(0, rangeIndicator);
endRange = range.Substring(rangeIndicator + 1, range.Length - rangeIndicator - 1);
if (startRange.TryParse(out startNum) && endRange.TryParse(out endNum) && startNum != 0 && endNum != 0) {
SetReverseNumber(ref startNum, maxValue);
SetReverseNumber(ref endNum, maxValue);
if (startNum < 0 || endNum < 0) {
continue;
}
r.Add(new PageRange(startNum, endNum));
}
}
else if (range.TryParse(out startNum)) {
SetReverseNumber(ref startNum, maxValue);
if (startNum < 0) {
continue;
}
r.Add(new PageRange(startNum, startNum));
}
}
}
if (r.Count == 0 && addDefaultRange) {
r.Add(new PageRange(minValue, maxValue));
}
else {
r.Collapse(minValue, maxValue);
}
return r;
}
static void SetReverseNumber(ref int refNum, int maxNum) {
if (refNum < 0) {
refNum = refNum + maxNum + 1;
}
}
public override string ToString() {
return String.Join(";", ConvertAll(r => r.ToString()).ToArray());
}
}
}