Files
PDFPatcher/App/Model/PageRangeCollection.cs
T
2021-12-24 20:35:03 +08:00

133 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
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 >= item.StartValue && value <= item.EndValue
|| value >= item.EndValue && value <= 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 = this.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) {
this.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) {
this.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 ();
r.Add (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) == false) {
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 (";", this.ConvertAll ((r) => { return r.ToString ();}).ToArray ());
}
}
}