using System;
using System.Text.RegularExpressions;
namespace NaGet.Packages
{
// TODO Debian-aptのコードを利用しているのでGPLになるのに注意
// 引用元: apt-pkg/deb/debversion.cc,v 1.8 2003/09/10 23:39:49 mdz Exp
// Debian Version - Versioning system for Debian
// This implements the standard Debian versioning system.
// Copyright (C) yyyy name of author
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
///
/// バージョン比較をするためのメソッドを含むクラス
///
public class VersionComparetor : System.Collections.Generic.IComparer
{
public VersionComparetor()
{
}
private static int order(char x)
{
return (char.IsDigit(x) ? 0
: (x==0) ? 0
: char.IsLetter(x) ? (x)
: (x) + 256);
}
public int Compare(string a, string b)
{
// 前処理
a = a.ToLower();
b = b.ToLower();
if (Regex.IsMatch(a, @"\.0*$"))
Regex.Replace(a, @"\.0*$", string.Empty);
if (Regex.IsMatch(b, @"\.0*$"))
Regex.Replace(b, @"\.0*$", string.Empty);
if (a == b) {
return 0;
}
int apos = 0, bpos = 0;
int alen = a.Length, blen = b.Length;
while ((apos < alen) && (bpos < blen)) {
int first_diff = 0;
while ((apos < alen) && (bpos < blen) &&
(!char.IsDigit(a[apos]) || !char.IsDigit(b[bpos])) ) {
int vc = order(a[apos]);
int rc = order(b[bpos]);
if (vc != rc)
return vc - rc;
apos ++; bpos ++;
}
if (a[apos] == '0') apos ++;
if (b[bpos] == '0') bpos ++;
while ((apos < alen) && (bpos < blen) &&
char.IsDigit(a[apos]) && char.IsDigit(b[bpos])) {
if (first_diff == 0)
first_diff = a[apos] - b[bpos];
apos ++; bpos ++;
}
if (apos < alen && char.IsDigit(a[apos])) {
return 1;
} else if (bpos < blen && char.IsDigit(b[bpos])) {
return -1;
} else if (first_diff != 0) {
return first_diff;
}
}
if (apos == alen && bpos == blen) {
return 0;
} else if (apos == alen) {
return -1;
} else if (bpos == blen) {
return 1;
} else {
return 1; // Shouldnt happen
}
}
}
}