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 } } } }