OSDN Git Service

Merge branch 'master' of git.sourceforge.jp:/gitroot/applistation/AppliStation
[applistation/AppliStation.git] / na-get-lib / NaGet.Packages / VersionComparetor.cs
1 using System;\r
2 using System.Text.RegularExpressions;\r
3 \r
4 namespace NaGet.Packages\r
5 {\r
6         // TODO Debian-aptのコードを利用しているのでGPLになるのに注意\r
7         \r
8         // 引用元: apt-pkg/deb/debversion.cc,v 1.8 2003/09/10 23:39:49 mdz Exp\r
9         //    Debian Version - Versioning system for Debian\r
10         //    This implements the standard Debian versioning system.\r
11         // Copyright (C) yyyy  name of author\r
12         // \r
13         // This program is free software; you can redistribute it and/or\r
14         // modify it under the terms of the GNU General Public License\r
15         // as published by the Free Software Foundation; either version 2\r
16         // of the License, or (at your option) any later version.\r
17         // \r
18         // This program is distributed in the hope that it will be useful,\r
19         // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20         // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
21         // GNU General Public License for more details.\r
22         // \r
23         // You should have received a copy of the GNU General Public License\r
24         // along with this program; if not, write to the Free Software\r
25         // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
26         \r
27         /// <summary>\r
28         /// バージョン比較をするためのメソッドを含むクラス\r
29         /// </summary>\r
30         public class VersionComparetor : System.Collections.Generic.IComparer<string>\r
31         {\r
32                 public VersionComparetor()\r
33                 {\r
34                 }\r
35                 \r
36                 private static int order(char x)\r
37                 {\r
38                         return (char.IsDigit(x) ? 0\r
39                                 : (x==0) ? 0\r
40                                 : char.IsLetter(x) ? (x)\r
41                                 : (x) + 256);\r
42                 }\r
43                 \r
44                 public int Compare(string a, string b)\r
45                 {\r
46                         // 前処理\r
47                         a = a.ToLower();\r
48                         b = b.ToLower();\r
49                         if (Regex.IsMatch(a, @"\.0*$")) \r
50                                 Regex.Replace(a, @"\.0*$", string.Empty);\r
51                         if (Regex.IsMatch(b, @"\.0*$")) \r
52                                 Regex.Replace(b, @"\.0*$", string.Empty);\r
53                         \r
54                         if (a == b) {\r
55                                 return 0;\r
56                         }\r
57                         \r
58                         \r
59                         int apos = 0, bpos = 0;\r
60                         int alen = a.Length, blen = b.Length;\r
61                         \r
62                         while ((apos < alen) && (bpos < blen)) {\r
63                                 int first_diff = 0;\r
64                                 \r
65                                 while ((apos < alen) && (bpos < blen) &&\r
66                                        (!char.IsDigit(a[apos]) || !char.IsDigit(b[bpos])) ) {\r
67                                         int vc = order(a[apos]);\r
68                                         int rc = order(b[bpos]);\r
69                                         if (vc != rc)\r
70                                                 return vc - rc;\r
71                                         apos ++; bpos ++;\r
72                                 }\r
73                                 \r
74                                 if (a[apos] == '0') apos ++;\r
75                                 if (b[bpos] == '0') bpos ++;\r
76                                 \r
77                                 while ((apos < alen) && (bpos < blen) &&\r
78                                        char.IsDigit(a[apos]) && char.IsDigit(b[bpos])) {\r
79                                         if (first_diff == 0)\r
80                                                 first_diff = a[apos] - b[bpos];\r
81                                         apos ++; bpos ++;\r
82                                 }\r
83                                 \r
84                                 if (apos < alen && char.IsDigit(a[apos])) {\r
85                                         return 1;\r
86                                 } else if (bpos < blen && char.IsDigit(b[bpos])) {\r
87                                         return -1;\r
88                                 } else if (first_diff != 0) {\r
89                                         return first_diff;\r
90                                 }\r
91                         }\r
92                         \r
93                         if (apos == alen && bpos == blen) {\r
94                                 return 0;\r
95                         } else if (apos == alen) {\r
96                                 return -1;\r
97                         } else if (bpos == blen) {\r
98                                 return 1;\r
99                         } else {\r
100                                 return 1; // Shouldnt happen\r
101                         }\r
102                 }\r
103                 \r
104                 \r
105         }\r
106 }\r