5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) Ximian, Inc. http://www.ximian.com
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 public sealed class Version : ICloneable,
38 IComparable, IComparable<Version>
44 int _Major, _Minor, _Build, _Revision;
46 private const int UNDEFINED = -1;
48 private void CheckedSet (int defined, int major, int minor, int build, int revision)
50 // defined should be 2, 3 or 4
53 throw new ArgumentOutOfRangeException ("major");
58 throw new ArgumentOutOfRangeException ("minor");
63 this._Build = UNDEFINED;
64 this._Revision = UNDEFINED;
69 throw new ArgumentOutOfRangeException ("build");
74 this._Revision = UNDEFINED;
79 throw new ArgumentOutOfRangeException ("revision");
81 this._Revision = revision;
86 CheckedSet (2, 0, 0, -1, -1);
89 public Version (string version)
93 int major = -1, minor = -1, build = -1, revision = -1;
95 if (version == null) {
96 throw new ArgumentNullException ("version");
99 vals = version.Split (new Char [] {'.'});
102 if (n < 2 || n > 4) {
103 throw new ArgumentException (Locale.GetText
104 ("There must be 2, 3 or 4 components in the version string."));
108 major = int.Parse (vals [0]);
110 minor = int.Parse (vals [1]);
112 build = int.Parse (vals [2]);
114 revision = int.Parse (vals [3]);
116 CheckedSet (n, major, minor, build, revision);
119 public Version (int major, int minor)
121 CheckedSet (2, major, minor, 0, 0);
124 public Version (int major, int minor, int build)
126 CheckedSet (3, major, minor, build, 0);
129 public Version (int major, int minor, int build, int revision)
131 CheckedSet (4, major, minor, build, revision);
152 public int Revision {
158 public object Clone ()
160 return new Version (_Major, _Minor, _Build, _Revision);
163 public int CompareTo (object version)
170 if (! (version is Version))
171 throw new ArgumentException (Locale.GetText ("Argument to Version.CompareTo must be a Version."));
173 v = version as Version;
175 if (this._Major > v._Major)
177 else if (this._Major < v._Major)
180 if (this._Minor > v._Minor)
182 else if (this._Minor < v._Minor)
185 if (this._Build > v._Build)
187 else if (this._Build < v._Build)
190 if (this._Revision > v._Revision)
192 else if (this._Revision < v._Revision)
198 public override bool Equals (object obj)
202 if (obj == null || !(obj is Version))
207 if ((x._Major == _Major) &&
208 (x._Minor == _Minor) &&
209 (x._Build == _Build) &&
210 (x._Revision == _Revision))
216 public int CompareTo (Version v)
218 if (this._Major > v._Major)
220 else if (this._Major < v._Major)
223 if (this._Minor > v._Minor)
225 else if (this._Minor < v._Minor)
228 if (this._Build > v._Build)
230 else if (this._Build < v._Build)
233 if (this._Revision > v._Revision)
235 else if (this._Revision < v._Revision)
241 public bool Equals (Version x)
243 if ((x._Major == _Major) &&
244 (x._Minor == _Minor) &&
245 (x._Build == _Build) &&
246 (x._Revision == _Revision))
252 public override int GetHashCode ()
254 return (_Revision << 24) | (_Build << 16) | (_Minor << 8) | _Major;
258 // Returns a stringified representation of the version, format:
259 // major.minor[.build[.revision]]
261 public override string ToString ()
263 string mm = _Major.ToString () + "." + _Minor.ToString ();
265 if (_Build != UNDEFINED)
266 mm = mm + "." + _Build.ToString ();
267 if (_Revision != UNDEFINED)
268 mm = mm + "." + _Revision.ToString ();
274 // LAME: This API is lame, since there is no way of knowing
275 // how many fields a Version object has, it is unfair to throw
276 // an ArgumentException, but this is what the spec claims.
278 // ie, Version a = new Version (1, 2); a.ToString (3) should
279 // throw the expcetion.
281 public string ToString (int fields)
286 return _Major.ToString ();
288 return _Major.ToString () + "." + _Minor.ToString ();
290 if (_Build == UNDEFINED)
291 throw new ArgumentException (Locale.GetText
292 ("fields is larger than the number of components defined in this instance."));
293 return _Major.ToString () + "." + _Minor.ToString () + "." +
297 if (_Build == UNDEFINED || _Revision == UNDEFINED)
298 throw new ArgumentException (Locale.GetText
299 ("fields is larger than the number of components defined in this instance."));
300 return _Major.ToString () + "." + _Minor.ToString () + "." +
301 _Build.ToString () + "." + _Revision.ToString ();
303 throw new ArgumentException (Locale.GetText ("Invalid fields parameter: ") + fields.ToString());
306 public static bool operator== (Version v1, Version v2)
308 return Equals (v1, v2);
311 public static bool operator!= (Version v1, Version v2)
313 return !Equals (v1, v2);
316 public static bool operator> (Version v1, Version v2)
318 return v1.CompareTo (v2) > 0;
321 public static bool operator>= (Version v1, Version v2)
323 return v1.CompareTo (v2) >= 0;
326 public static bool operator< (Version v1, Version v2)
328 return v1.CompareTo (v2) < 0;
331 public static bool operator<= (Version v1, Version v2)
333 return v1.CompareTo (v2) <= 0;
336 // a very gentle way to construct a Version object which takes
337 // the first four numbers in a string as the version
338 internal static Version CreateFromString (string info)
345 int number = UNDEFINED; // string may not begin with a digit
347 for (int i=0; i < info.Length; i++) {
349 if (Char.IsDigit (c)) {
354 number = (number * 10) + (c - '0');
357 else if (number >= 0) {
376 // ignore end of string
380 return new Version (major, minor, build, revision);